home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1994-09-20 | 162.8 KB | 4,313 lines
Notes on the inner workings of XEmacs ---------------------------------------------------------------------- ---------------------------- allocation ------------------------------ ---------------------------------------------------------------------- 1. Lowest-level allocation: Lisp_Object malloc_warning_1 (str) void malloc_warning (str) memory_full () long * xmalloc (size) long * xrealloc (block, size) xmalloc() and xrealloc() call malloc() and realloc(), and if the result returned is 0 (no free memory), call memory_full(). malloc_warning() is called by malloc() when there is almost no free memory, and in turn calls malloc_warning_1() to issue a warning to the user. Note that Emacs has its own malloc(), realloc(), and free() defined in malloc.c. 2. General: VALIDATE_LISP_STORAGE(address, size) INCREMENT_CONS_COUNTER(size) int consing_since_gc; int gc_cons_threshold; /* Nonzero during gc */ int gc_in_progress; /* Nonzero when calling the hooks in Energize-beta */ Lisp_Object Qgc_currently_forbidden; int gc_currently_forbidden; [some other stuff] VALIDATE_LISP_STORAGE() is called whenever a new address is returned from malloc() that is supposed to go within a Lisp object. It verifies that the address will actually fit (since Lisp addresses have to fit within 24 or 26 bits) and calls memory_full() if not. INCREMENT_CONS_COUNTER() is called whenever certain Lisp objects are created, and updates consing_since_gc, the number of bytes of Lisp objects created since the last garbage collection. When this number reaches gc_cons_threshold, a garbage collection is begun. [INCREMENT_CONS_COUNTER() optionally calls cadillac_record_backtrace(); what is this?] 3. Creation of primitive objects: static void init_extents () EXTENT make_extent () DUP make_extent_replica () 3a. cons void init_cons () free_cons (ptr) DEFUN ("cons", Fcons, Scons, 2, 2, 0, "Create a new cons, give it CAR and CDR as components, and return it.") (car, cdr) #define CONS_BLOCK_SIZE \ ((1020 - sizeof (struct cons_block *)) / sizeof (struct Lisp_Cons)) struct cons_block { struct cons_block *next; struct Lisp_Cons conses[CONS_BLOCK_SIZE]; }; struct cons_block *cons_block; int cons_block_index; struct Lisp_Cons *cons_free_list; Cons cells are stored in cons blocks (struct cons_block), which contain a "next" field and an array of conses. cons blocks are calculated to occupy exactly 1024 bytes of memory including malloc info. "cons_block" points to the first (most recent) cons block in the chain. As cons cells are freed, they are added to the cons_free_list (threaded through the car field), and new cells are taken from this list first. If no more such cells are available, a new is obtained from the current cons block (cons_block_index specifies the index of the next free cell), and if there are no free cells, a new cons block is created. VALIDATE_LISP_STORAGE() and INCREMENT_CONS_COUNT() are called as necessary. init_cons() creates the first cons block, and Fcons() and free_cons() create and free cons cells as indicated. 3b. list DEFUN ("list", Flist, Slist, 0, MANY, 0, "Return a newly created list with specified arguments as elements.\n\ Any number of arguments, even zero arguments, are allowed.") (nargs, args) DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, "Return a newly created list of length LENGTH, with each element being INIT.") (length, init) No surprises here. Fmake_list() creates a list of specified length by calling Fcons() repeatedly and Flist() calls Fmake_list() and then traipses down the list, filling in the "car" fields. 3c. float void init_float () free_float (ptr) Lisp_Object make_float (float_value) #define FLOAT_BLOCK_SIZE \ ((1020 - sizeof (struct float_block *)) / sizeof (struct Lisp_Float)) struct float_block { struct float_block *next; struct Lisp_Float floats[FLOAT_BLOCK_SIZE]; }; struct float_block *float_block; int float_block_index; struct Lisp_Float *float_free_list; Floats are allocated exactly like cons cells above. Floats on the free list are threaded through the "type" field. 3d. vector struct Lisp_Vector *all_vectors; DEFUN ("make-vector", Fmake_vector, Smake_vector, 2, 2, 0, "Return a newly created vector of length LENGTH, with each element being INIT.\n\ See also the function `vector'.") (length, init) DEFUN ("vector", Fvector, Svector, 0, MANY, 0, "Return a newly created vector with specified arguments as elements.\n\ Any number of arguments, even zero arguments, are allowed.") (nargs, args) Each vector is allocated as a chunk of memory of the right size, and all vectors are kept on the list "all_vectors", threaded through the "next" field. Note that "struct Lisp_Vector" appears to contain space for only one element. However, indexing off the end of this array simply accesses the rest of the space allocated for the elements. 3e. byte code objects (DEFUN ("make-byte-code", Fmake_byte_code, Smake_byte_code, 4, MANY, 0, "Create a byte-code object with specified arguments as elements.\n\ At least four arguments are required; only six have any significance.") (nargs, args) calls make_pure_vector(); [what does this do?] 3f. symbols #define SYMBOL_BLOCK_SIZE \ ((1020 - sizeof (struct symbol_block *)) / sizeof (struct Lisp_Symbol)) struct symbol_block { struct symbol_block *next; struct Lisp_Symbol symbols[SYMBOL_BLOCK_SIZE]; }; struct symbol_block *symbol_block; int symbol_block_index; struct Lisp_Symbol *symbol_free_list; void init_symbol () DEFUN ("make-symbol", Fmake_symbol, Smake_symbol, 1, 1, 0, "Return a newly allocated uninterned symbol whose name is NAME.\n\ Its value and function definition are void, and its property list is nil.") (str) #define MARKER_BLOCK_SIZE \ ((1020 - sizeof (struct marker_block *)) / sizeof (struct Lisp_Marker)) Symbols are allocated exactly like cons cells above. The symbol's name is bound to the string given, the symbol's plist is bound to Qnil, and the function and value fields are marked unbound (bound to variable Qunbound). Symbols on the free list are threaded through the "next" field, which is also used for threading in an obarray. 3g. markers struct marker_block { struct marker_block *next; struct Lisp_Marker markers[MARKER_BLOCK_SIZE]; }; struct marker_block *marker_block; int marker_block_index; struct Lisp_Marker *marker_free_list; void init_marker () DEFUN ("make-marker", Fmake_marker, Smake_marker, 0, 0, 0, "Return a newly allocated marker which does not point at any place.") () Markers are allocated exactly like cons cells above. Markers on the free list are threaded through the "chain" field. 3h. string static void init_strings () static struct Lisp_String * make_string_internal () static struct string_chars * allocate_string_chars (size, fullsize) static Lisp_Object make_uninit_string (length) DEFUN ("make-string", Fmake_string, Smake_string, 2, 2, 0, "Return a newly created string of length LENGTH, with each element being INIT.\n\ Both LENGTH and INIT must be numbers.") (length, init) Lisp_Object make_string_from_buffer (buf, index, length) Lisp_Object make_string (contents, length) Lisp_Object build_string (str) Lisp_Object make_pure_string (data, length) /* If SIZE is the length of a string, this returns how many bytes the string occupies in a string_chars_block (including padding). */ #define PAD ((sizeof (struct Lisp_String *)) - 1) #define ROUND_UP_STRING_SIZE(s) (((s) + 1 + PAD) & ~PAD) #define STRING_FULLSIZE(size) \ ROUND_UP_STRING_SIZE ((size) + sizeof (struct Lisp_String *)) #define STRING_BLOCK_SIZE \ ((1020 - sizeof (struct string_block *)) / sizeof (struct Lisp_String)) /* String blocks contain this many useful bytes. 8188 is power of 2, minus 4 for malloc overhead. */ #define STRING_CHARS_BLOCK_SIZE \ (8188 - ((2 * sizeof (struct string_chars_block *))+ sizeof (int))) struct string_chars { struct Lisp_String *string; unsigned char chars[1]; }; #define SLOT_OFFSET(type, slot_name) \ ((unsigned) (((char *) (&(((type *)0)->slot_name))) - ((char *) 0))) #define CHARS_TO_STRING_CHAR(x) \ ((struct string_chars *)\ (((char *) (x)) - (SLOT_OFFSET(struct string_chars, chars)))) /* Block header for small strings. */ struct string_chars_block { struct string_chars_block *next; struct string_chars_block *prev; int pos; unsigned char chars[STRING_CHARS_BLOCK_SIZE]; }; struct string_block { struct string_block *next; struct Lisp_String strings[STRING_BLOCK_SIZE]; }; struct string_block *string_block; static int string_block_index; static struct Lisp_String *string_free_list; struct string_chars_block *current_string_chars_block; struct string_chars_block *first_string_chars_block; #define NONRELOCATING_STRING_SIZE(size) ((size) >= 1020) #define BIG_STRING_SIZE(size) (NONRELOCATING_STRING_SIZE(size)) struct Lisp_String { int size; Lisp_Object dup_list; unsigned char *data; } A string consists of a struct Lisp_String, plus the actual string data. The struct Lisp_String consists of the length of the string and a pointer to the data, plus a chain field "dup_list", used for threading the list of free struct Lisp_String's. struct Lisp_String's are managed exactly like cons cells. make_string_internal() returns a pointer to a new struct Lisp_String. The string data itself is stored in struct string_chars_block's, if the string is less than a certain size (about 1K bytes). A struct string_chars_block occupies exactly 8K bytes, and holds a certain amount of raw storage plus forward and backward link pointers and an index into the storage, indicating where the unused part starts. The storage is chunked out in struct string_chars's, each of which consists of a pointer to the struct Lisp_String for this string plus the actual string data, padded out to a multiple of 4 bytes. A new struct string_chars_block is allocated if the existing one does not have enough space, and all such structures are linked together and pointed to by first_string_chars_block and current_string_chars_block. If the string is larger than about 1K bytes (see BIG_STRING_SIZE() and NONRELOCATING_STRING_SIZE()), a struct string_chars of the proper size is simply malloc()ed. allocate_string_chars() allocates and returns a struct string_chars() of the proper size. make_uninit_string() uses this function and make_string_internal(), and returns a Lisp_Object that points to a completed struct Lisp_String. make-string, make_string(), and build_string() call make_uninit_string() and then fill in the data. make_string_from_buffer(), which makes a string from a section of a buffer's text, is similar but first moves the gap out the way and also calls replicate_extents() [see ?????] (see "buffers"). 3i. pure Lisp_Object pure_cons (car, cdr) Lisp_Object make_pure_float (num) Lisp_Object make_pure_vector (len, stat_type) make_pure_vector (len) DEFUN ("purecopy", Fpurecopy, Spurecopy, 1, 1, 0, "Make a copy of OBJECT in pure storage.\n\ Recursively copies contents of vectors and cons cells.\n\ Does not copy symbols.") (obj) 4. garbage collection void staticpro (varaddress) void BTL_before_Fgarbage_collect_stub () static void mark_object (), mark_buffer () static void mark_event (), mark_command_event_queue () static void clear_marks (), gc_sweep () static void compact_string_chars () static void mark_one_extent (extent) static void mark_extents (extent) static void mark_object (objptr) static void mark_buffer (buffer) static void mark_event (ptr) static void mark_command_event_queue () static void gc_sweep () static void compact_string_chars () DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "", "Reclaim storage for Lisp objects no longer needed.\n\ Returns info on amount of space in use:\n\ ((USED-CONSES . FREE-CONSES) (USED-SYMS . FREE-SYMS)\n\ (USED-MARKERS . FREE-MARKERS) USED-STRING-CHARS USED-VECTOR-SLOTS\n\ (USED-FLOATS . FREE-FLOATS) (USED-EVENTS . FREE-EVENTS))\n\ Garbage collection happens automatically if you cons more than\n\ `gc-cons-threshold' bytes of Lisp data since previous garbage collection.") () init_alloc_once () init_alloc () void syms_of_alloc () Garbage collection involves going through all referenceable memory and marking it, and then freeing all unreferenceable memory. Garbage collection can happen any time anything is evaluated. If a function creates a cons cell or anything else that is allocated and then calls any function that might directly or indirectly call Feval(), it must "protect" or "gcpro" that object; this involves putting it on a list of referenced objects that garbage-collect pays attention to. The object must be ungcpro'ed when done. The macros GCPRO1(), GCPRO2(), GCPRO3(), and GCPRO4() protect that many objects, and use local variables struct gcpro gcpro1, gcpro2, gcpro3, and gcpro4, which must have been declared at the top of the function. These macros actually store the address of the passed object(s) into the appropriate struct gcpro(s) and add the structure(s) onto the head of the linked list pointed to by "gcprolist". The reason for storing the addresses, and not the objects themselves, is so that the variables holding the objects can be modified if the object is relocated, and also so that things still work correctly if you change the value of the variable holding the object. Consequently, you must give lvalues as arguments to GCPRO*(). UNGCPRO() removes the struct gcpro's off the list. staticpro() is similar to GCPRO() for global and static variables and adds an entry to the array staticvec[]. Garbage collection looks in the following places to find referenced memory: 1) variables on the staticvec[] list, added with staticpro(). 2) variables on the gcprolist. 3) objects in any backtrace structures on the backtrace_list. (see "eval") 4) specpdl 5) catchlist 6) handlerlist 7) any objects referenced by objects discovered above (e.g. if a cons is referenced, then its car and cdr are also referenced). Note that all symbols in the obarray (i.e. all global symbols) are marked, because (1) obarray (a vector) is staticpro'd, (2) when marking a vector all its elements are marked, and (3) when marking a symbol, the symbol pointed to by the "next" field is marked. The next field is used to link together symbols on the free list, but for in-use symbols is always 0 unless the symbol is in an obarray. ---------------------------------------------------------------------- ----------------------------- bitmaps -------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- ----------------------------- buffers -------------------------------- ---------------------------------------------------------------------- [buffer.c, buffer.h] struct buffer_text { unsigned char *beg; /* Actual address of buffer contents. */ int begv; /* Index of beginning of accessible range. */ int pt; /* Position of point in buffer. */ int gpt; /* Index of gap in buffer. */ int zv; /* Index of end of accessible range. */ int z; /* Index of end of buffer. */ int gap_size; /* Size of buffer's gap */ int modiff; /* This counts buffer-modification events for this buffer. It is incremented for each such event, and never otherwise changed. */ int face_change; /* This is set when a change in how the text should be displayed (e.g., font, color) is made. */ }; struct buffer { /* Everything before the `name' slot must be of a non-Lisp_Object type, and every slot after `name' must be a Lisp_Object. Check out mark_buffer (alloc.c) to see why. */ /* This structure holds the coordinates of the buffer contents. */ struct buffer_text text; /* Next buffer, in chain of all buffers including killed buffers. This chain is used only for garbage collection, in order to collect killed buffers properly. */ struct buffer *next; /* Flags saying which DEFVAR_PER_BUFFER variables are local to this buffer. */ int local_var_flags; /* Value of text.modiff when buffer last saved */ int save_modified; /* Set to the modtime of the visited file when read or written. -1 means visited file was nonexistent. 0 means visited file modtime unknown; in no case complain about any mismatch on next save attempt. */ int modtime; /* the value of text.modiff at the last auto-save. */ int auto_save_modified; /* Position in buffer at which display started the last time this buffer was displayed */ int last_window_start; struct stack_of_extents *cached_stack; /* These next two are exceptions -- both slots are be handled "specially" by gc_sweep, and their contents are not lisp-accessible as a local variable, but they are Lisp_Objects. */ /* The markers that refer to this buffer. This is actually a single marker -- successive elements in its marker `chain' are the other markers referring to this buffer */ Lisp_Object markers; /* Active regions in this buffer. */ Lisp_Object extents; /* Everything from here down must be a Lisp_Object */ /* the name of this buffer */ Lisp_Object name; #undef MARKED_SLOT #define MARKED_SLOT(x) Lisp_Object x #include "bufslots.h" }; bufslots.h: /* the name of the file associated with this buffer */ MARKED_SLOT (filename); /* the truename of the filename (via the realpath() system call) */ MARKED_SLOT (truename); /* Dir for expanding relative pathnames */ MARKED_SLOT (directory); /* true iff this buffer has been been backed up (if you write to its associated file and it hasn't been backed up, then a backup will be made) */ MARKED_SLOT (backed_up); /* Length of file when last read or saved. */ MARKED_SLOT (save_length); /* file name used for auto-saving this buffer */ MARKED_SLOT (auto_save_file_name); /* Non-nil if buffer read-only */ MARKED_SLOT (read_only); /* "The mark"; no longer allowed to be nil */ MARKED_SLOT (mark); /* Alist of elements (SYMBOL . VALUE-IN-THIS-BUFFER) for all per-buffer variables of this buffer. */ MARKED_SLOT (local_var_alist); /* Symbol naming major mode (eg lisp-mode) */ MARKED_SLOT (major_mode); /* Pretty name of major mode (eg "Lisp") */ MARKED_SLOT (mode_name); /* Format string for mode line */ MARKED_SLOT (mode_line_format); /* Keys that are bound local to this buffer */ MARKED_SLOT (keymap); /* Local bindings for mouse buttons, expressed as a keymap. */ MARKED_SLOT (mouse_map); /* Local bindings for function keys. */ MARKED_SLOT (function_key_map); /* This buffer's local abbrev table */ MARKED_SLOT (abbrev_table); /* This buffer's syntax table. */ MARKED_SLOT (syntax_table); /* Values of several buffer-local variables. tab-width is buffer-local so that redisplay can find it in buffers that are not current */ MARKED_SLOT (case_fold_search); MARKED_SLOT (tab_width); MARKED_SLOT (fill_column); MARKED_SLOT (left_margin); /* Function to call when insert space past fill column */ MARKED_SLOT (auto_fill_function); /* String of length 256 mapping each char to its lower-case version. */ MARKED_SLOT (downcase_table); /* String of length 256 mapping each char to its upper-case version. */ MARKED_SLOT (upcase_table); /* Non-nil means do not display continuation lines */ MARKED_SLOT (truncate_lines); /* Non-nil means display ctl chars with uparrow */ MARKED_SLOT (ctl_arrow); /* Non-nil means do selective display; See doc string in syms_of_buffer (buffer.c) for details. */ MARKED_SLOT (selective_display); #ifndef old /* Non-nil means show ... at end of line followed by invisible lines. */ MARKED_SLOT (selective_display_ellipses); #endif /* Alist of (FUNCTION . STRING) for each minor mode enabled in buffer. */ MARKED_SLOT (minor_modes); /* t if "self-insertion" should overwrite */ MARKED_SLOT (overwrite_mode); /* non-nil means abbrev mode is on. Expand abbrevs automatically. */ MARKED_SLOT (abbrev_mode); /* Display table to use for text in this buffer. */ MARKED_SLOT (display_table); /* Translate table for case-folding search. */ MARKED_SLOT (case_canon_table); /* Inverse translate (equivalence class) table for case-folding search. */ MARKED_SLOT (case_eqv_table); /* Changes in the buffer are recorded here for undo. t means don't record anything. */ MARKED_SLOT (undo_list); /* A redundant copy of text.pt, in the form of a marker. Every time one is updated, so is the other. */ MARKED_SLOT (point_marker); /* If dedicated_screen is non-nil, display_buffer tries to use it instead of the current screen */ MARKED_SLOT (dedicated_screen); ------- Vbuffer_alist, a Lisp object, holds an assoc-list mapping strings (buffer names) to buffer objects. Furthermore, each screen contains its own buffer_alist, which holds the same information but possibly in a different order. Fbuffer_list(), Fget_buffer(), and Fget_file_buffer() do the expected things, working on the buffer list(s). push_buffer_alist() and delete_from_buffer_alist() add to the end of or delete from all the buffer lists. struct buffer holds all the info for a buffer. This includes struct buffer_text (which holds the actual text), built-in buffer-local variables, plus various other things. Each struct buffer is separately malloc'ed() and all allocated buffers are linked together through the field "next". A pointer to the current buffer is contained in "current_buffer". struct buffer_text: The text in a buffer is maintained consecutively in memory, with the exception of a "gap" somewhere in the text. Inserting text is done by moving the gap to the right place in the text and then copying the text in. If the gap is too small to hold the text, it is enlarged and all the following text is moved to accommodate it. Since this is an expensive operation, the size of the new gap is made quite large (specifically, 2000 plus one-tenth the size of the buffer). This is very efficient when there is a lot of locality in the insertion, and has the advantage that accessing the character at a particular position is still relatively easy. When text is deleted, a similar process is followed -- the gap is moved to where the deletion should occur and is enlarged appropriately. There is currently no limit on the size of the gap, meaning that memory allocated for a buffer will never be freed until the buffer is killed. [does it happen even then?] When inserting and deleting text, it is also necessary to change the various positions and markers. The elements of struct buffer_text are: struct buffer_text { unsigned char *beg; /* Actual address of buffer contents. */ int begv; /* Index of beginning of accessible range. */ int pt; /* Position of point in buffer. */ int gpt; /* Index of gap in buffer. */ int zv; /* Index of end of accessible range. */ int z; /* Index of end of buffer. */ int gap_size; /* Size of buffer's gap */ int modiff; /* This counts buffer-modification events for this buffer. It is incremented for each such event, and never otherwise changed. */ int face_change; /* This is set when a change in how the text should be displayed (e.g., font, color) is made. */ }; Note that character indices into buffers begin at 1. Numerous macros are defined to make accessing the above fields easier: BUF_CHAR_ADDRESS(buf, pos) and CHAR_ADDRESS(pos) [for the current buffer] return the address of the character specified by the given index. They call BUF_TRUE_POS(buf, pos), which adjusts a character index by the appropriate amount if it is after the gap. PTR_CHAR_POS(pos) [for the current buffer], reverses this process and returns the index corresponding to the given address. BUF_CHAR_AT(buf, pos) and CHAR_AT(pos) return the actual character at the given index. BEGV, PT, GPT, ZV, Z, MODIFF, GAP_SIZE, and FACECHANGE access the corresponding elements in the current buffer. BEG and BEG_ADDR return the index and address of the beginning of the current buffer (note that BEG is always 1). BEGV_ADDR, PT_ADDR, GPT_ADDR and ZV_ADDR return the addresses corresponding to the specified indices for the current buffer. GAP_END_ADDR returns the address of the character in the current buffer following the end of the gap. Corresponding macros BUF_BEGV, BUF_PT, BUF_GPT, BUF_ZV, BUF_Z, BUF_MODIFF, BUF_GAP_SIZE, BUF_FACECHANGE, BUF_BEG, and BUF_BEG_ADDR work on a specified buffer. [there's some more junk in buffer.h] Manipulating the gap: void gap_left (pos, newgap) void gap_right (pos) void move_gap (pos) void make_gap (increment) move_gap() moves the gap the specified amount up or down, calling gap_left() or gap_right to do the work. They work as expected, except that they (optionally) change beg_unchanged and end_unchanged [look these up], check for ^G every 32,000 characters [look up macro QUIT], and call adjust_markers() and adjust_extents() when done. make_gap() increases the gap at least by the specified size, according to the formula above. It calls BUFFER_REALLOC() to make more space and calls gap_left() to move the new "end gap" consecutive with the old gap, inhibiting ^G throughout. Inserting text: void insert_relocatable_raw_string (string, length, obj) void insert_from_string (obj, pos, length) void insert_raw_string (string, length) void insert (string, length) void insert_string (s) void insert_char (c) void insert_before_markers (string, length) void insert_from_string_before_markers (string, pos, length) void insert_buffer_string (b, index, length) The two routines that actually insert text are insert_relocatable_raw_string() and insert_from_string(). insert_raw_string(), insert(), insert_string(), and insert_char() do the same thing, the former two just calling insert_relocatable_raw_string() with a NULL pointer passed as obj, and the latter two just calling insert_raw_string() with the correct length. void adjust_markers (from, to, amount) void prepare_to_modify_buffer (start, end) void modify_region (start, end) static Lisp_Object before_change_function_restore (value) static Lisp_Object after_change_function_restore (value) signal_before_change (start, end) signal_after_change (pos, lendel, lenins) void del_range (from, to) Creation of a new buffer is actually done in Fget_buffer_create(). ---------------------------------------------------------------------- ------------------------------ display ------------------------------- ---------------------------------------------------------------------- /* Nonzero if head_clip or tail_clip of current buffer has changed since last redisplay that finished */ int clip_changed; /* Nonzero if window sizes or contents have changed since last redisplay that finished */ int windows_or_buffers_changed; void mark_window_display_accurate(window, accurate_p) Specifies whether void redraw_screen(screen) Sets up the screen for complete redisplay. Physically clears the screen and sets various flags to indicate that the entire contents of the screen are garbaged. redraw-screen Lisp entry to redraw_screen(). redraw-display Calls redraw-screen on all screens. redisplay() Main external entry point for redisplay. Updates all screens on the physical display. 1) update_psheets() 2) in_display++ 3) invalidate each screen's desired glyphs (reset the enable[] array). 4) deal with the echo area. 5) update the redisplay structure (desired glyphs): a) if only local changes were made, take a shortcut. b) otherwise redo the whole structure (redisplay_window()). 6) update the physical screen. Calls update_screen() on any screens that need to be updated. 7) mark the updated windows as accurate. 8) in_display-- 9) update_screen_menubars() redisplay_windows(window) Redisplay the specified window and all the siblings after it. Calls redisplay_window(). redisplay_window(window, just_this_one) Redisplay the specified window. If this is a combination window, redisplay all its children through redisplay_windows(). Does not actually change the physical display. Calls try_window() or try_window_id(). try_window(window, pos) Do a full redisplay on the specified window. Does not actually change the physical display. Called by redisplay_window(). try_window_id(window) Attempt to do a redisplay on the specified window when only local changes happened. Does not actually change the physical display. Called by redisplay_window(). int update_screen(screen, force, inhibit_hairy_id) Update a screen. Essentially calls update_line() or x_update_line() on each line. Break off updating if input is pending, unless "force" is non-zero. Return value is non-zero is update broken off due to pending input. 1. if not "force" and input is pending, invalidate all the lines of the screen's desired glyphs and return. 2. update_begin() (just sets updating_screen) 3. if ... 4. loop over all lines (possibly breaking if input pending) -- if the line in desired glyphs is valid, display it with x_update_line() 5. set the cursor position properly 6. invalidate desired glyphs. 7. update_end() 8. deal with the termscript if necessary void x_update_line(screen, vpos, pix_y) Update line "vpos" on screen "screen". "pix_y" is the position of the top of the line, in pixels. Calls x_write_glyphs(), x_clear_display_line(), and x_clear_display_line_end() as necessary. 1. save the characteristics for this line in current glyphs (for use later on in this function) 2. move the characteristics in desired glyphs for this line into current glyphs 3. if the line is blank, erase any line that might have been there before (x_clear_display_line()) and return. 4. otherwise, attempt to do the minimum amount of effort to get a correctly displayed line. You figure out what's going on here. I don't think it's robust. x_clear_display_line(), x_write_glyphs(), and/or x_clear_display_line_end() may be called. void x_clear_display_line(vpos, pix_width) void x_clear_display_line_end(vpos) Clear a line or part of a line. Calls XClearArea(). int x_write_glyphs(screen, left, top, n, force_gc, box_p) The routine that actually draws text or a cursor. "left" and "top" specify the position in characters where the drawing starts. "n" specifies the number of characters to write. "box_p" specifies whether to draw a box around the text. ["force_gc"?] Looks in "current_glyphs" to get text to write. 1. If any parameters are invalid or something is wrong with current_glyphs, return. (abort?) 2. Erase the cursor if it's in the region we're writing to. 3. Find the correct run. 4. Deal with graphics contexts. /** CHANGE **/ 5. Find the correct place within the run; determine the pixel offset where we should start displaying. 6. If the run to be displayed is text: a. clear the area to be displayed in, if necessary. b. display the text, displaying a box if necessary. Apparently deals with the background or whatever. [?] c. deal with underlining. (this should be done in the callback routine) 7. If the run to be displayed is "column_glyph": 8. If the run to be displayed is a "glyph" (bitmap), display the bitmap. Does some odd junk. 9. If the run to be displayed is "space": 10. Loop till all glyphs are displayed. xx. displaying/removing the cursor void erase_screen_cursor_if_needed(screen) void erase_cursor_if_needed(void) void erase_screen_cursor_if_needed_and_in_region(screen, x, y, n) void draw_screen_cursor_if_needed(screen) void x_screen_redraw_cursor(screen) Draw or erase a cursor, either for the specified screen or the currently active screen (current_screen or updating_screen). Possibly only remove cursor if it's on the specified line and between character positions "x" and "x+n" inclusive. Calls x_display_cursor(). void x_display_bar_cursor(screen, on) int x_draw_empty_box(screen) int x_draw_square(screen) int x_erase_square(screen) int x_display_box_cursor(screen, on) int x_display_cursor(screen, on) Actually do the cursor displaying/removing. Calls XClearArea() or x_write_glyphs(). other: x_draw_lineinfo_border() x_clear_lineinfo_glyph() XTwrite_glyphs() XTclear_end_of_line() XTclear_screen() XTflash() XTsimple_beep() XTring_bell() XTset_terminal_window() stufflines() scraplines() XTins_del_lines() repaint_lines() x_new_selected_screen() x_event_name() x_error_handler() x_IO_error_handler() #ifdef ENERGIZE reasonable_glyph_index_p() allocate_x_bitmaps() possible_energize_glyph_index_p() allocate_x_bitmaps_index() free_all_x_bitmaps_indices() free_x_bitmaps_index() #endif init_bitmap_tables() report_broken_pipe() make_argc_argv() make_arg_list() x_term_init() x_update_wm_hints() x_calc_absolute_position() x_set_offset() x_set_window_size() x_set_mouse_position() handle_raise_error() x_raise_screen() x_lower_screen() x_make_screen_visible() x_make_screen_invisible() x_iconify_screen() x_focus_screen() x_destroy_window() ---------------------------------------------------------------------- -------------------------------- eval -------------------------------- ---------------------------------------------------------------------- struct backtrace { struct backtrace *next; Lisp_Object *function; Lisp_Object *args; /* Points to vector of args. */ int nargs; /* length of vector */ /* if nargs is UNEVALLED, args points to slot holding list of unevalled args */ #ifdef EMACS_BTL /* The value of a Lisp integer that specifies the symbol being "invoked" by this node in the backtrace, or 0 if the backtrace doesn't correspond to a such an invocation */ int id_number; #endif char evalargs; char debug_on_exit; /* Nonzero means call value of debugger when done with this operation. */ }; Feval() evaluates the form (a Lisp object) that is passed to it. Note that evaluation is only non-trivial for two types of objects: symbols and conses. Under normal circumstances (i.e. not mocklisp) a symbol is evaluated simply by calling symbol-value on it and returning the value. Evaluating a cons means calling a function. First, eval checks to see if garbage-collection is necessary, and calls Fgarbage_collect() if so. It then increases the evaluation depth by 1 (lisp_eval_depth and max_lisp_eval_depth) and adds an element to the linked list of struct backtrace's ("backtrace_list"). Each such structure contains a pointer to the function being called plus a list of the function's arguments. Originally these values are stored unevalled, and as they are evaluated, the backtrace structure is updated. Garbage collection pays attention to the objects pointed to in the backtrace structures (garbage collection might happen while a function is being called or while an argument is being evaluated, and there could easily be no other references to the arguments in the argument list; once an argument is evaluated, however, the unevalled version is not needed by eval, and so the backtrace structure is changed). At this point, the function to be called is determined by looking at the car of the cons (if this is a symbol, its function definition is retrieved and the process repeated). The function should then consist of either a Lisp_Subr (built-in function), a Lisp_Compiled object, or a cons whose car is the symbol "autoload", "macro", "lambda", or "mocklisp". If the function is a Lisp_Subr, the lisp object points to a struct Lisp_Subr (created by DEFUN()), which contains a pointer to the C function, a minimum and maximum number of arguments (possibly the special constants MANY or UNEVALLED), a pointer to the symbol referring to that subr, and a couple of other things. If the subr wants its arguments UNEVALLED, they are passed raw as a list. Otherwise, an array of evaluated arguments is created and put into the backtrace structure, and either passed whole (MANY) or each argument is passed as a C argument. If the function is a Lisp_Compiled object or a lambda, apply_lambda() is called. If the function is a macro, [..... fill in] is done. If the function is an autoload, do_autoload() is called to load the definition and then eval starts over [explain this more]. If the function is a mocklisp, ml_apply() is called. When eval exits, the evaluation depth is reduced by one, the debugger is called if appropriate, and the current backtrace structure is removed from the list. apply_lambda() is passed a function, a list of arguments, and a flag indicating whether to evaluate the arguments. It creates an array of (possibly) evaluated arguments and fixes up the backtrace structure, just like eval does. Then it calls funcall_lambda(). funcall_lambda() goes through the formal arguments to the function and binds them to the actual arguments, checking for "&rest" and "&optional" symbols in the formal arguments and making sure the number of actual arguments is correct. Then either progn or byte-code is called to actually execute the body and return a value. Ffuncall() implements Lisp "funcall". (funcall fun x1 x2 x3 ...) is equivalent to (eval (list fun (quote x1) (quote x2) (quote x3) ...)). Ffuncall() contains its own code to do the evaluation, however, and is almost identical to eval. Fapply() implements Lisp "apply", which is very similar to funcall except that if the last argument is a list, the result is the same as if each of the arguments in the list had been passed separately. Fapply() does some business to expand the last argument if it's a list, then calls Ffuncall() to do the work. apply1(), call0(), call1(), call2(), and call3() call a function, passing it the argument(s) given (the arguments are given as separate C arguments rather than being passed as an array). apply1() uses "apply" while the others use "funcall". 2. specbindings struct specbinding { Lisp_Object symbol, old_value; Lisp_Object (*func) (); Lisp_Object unused; /* Dividing by 16 is faster than by 12 */ }; struct specbinding is used for local-variable bindings and unwind-protects. "specpdl" holds an array of struct specbinding's, "specpdl_ptr" points to the beginning of the free bindings in the array, "specpdl_size" specifies the total number of binding slots in the array, and "max_specpdl_size" specifies the maximum number of bindings the array can be expanded to hold. grow_specpdl() increases the size of the specpdl array, multiplying its size by 2 but never exceeding max_specpdl_size (except that if this number is less than 400, it is first set to 400). specbind() binds a symbol to a value and is used for local variables and "let" forms. The symbol and its old value (which might be Qunbound, indicating no prior value) are recorded in the specpdl array, and specpdl_size is increased by 1. record_unwind_protect() implements an unwind-protect, which, when placed around a section of code, ensures that some specified cleanup routine will be executed even if the code exits abnormally (e.g. through a throw or quit). record_unwind_protect() simply adds a new specbinding to the specpdl array and stores the appropriate information in it. The cleanup routine can either be a C function, which is stored in the "func" field, or a progn form, which is stored in the "old_value" field. unbind_to() removes specbindings from the specpdl array until the specified position is reached. The specbinding can be one of three types: (1) an unwind-protect with a C cleanup function ("func" is not 0 -- old_value holds an argument to be passed to the function); (2) an unwind-protect with a Lisp form ("func" is 0 and "symbol" is NIL -- old_value holds the form to be executed with Fprogn()); or (3) a local-variable binding ("func" is 0 and "symbol" is not NIL -- old_value holds the old value, which is stored as the symbol's value). 3. special forms 3a. or, and, if, cond, progn, prog1, prog2, setq, quote, function, let*, let, while All of these are very simple and work as expected, calling Feval() or Fprogn() as necessary and (in the case of let and let*) using specbind() to create bindings and unbind_to() to undo the bindings when finished. Note that these functions do a lot of GCPRO()ing to protect their arguments from garbage collection because they call Feval() (see "garbage collection"). 3b. catch, throw struct catchtag { Lisp_Object tag; Lisp_Object val; struct catchtag *next; struct gcpro *gcpro; jmp_buf jmp; struct backtrace *backlist; int lisp_eval_depth; int pdlcount; }; "catch" is a Lisp function that places a catch around a body of code. A catch is a means of non-local exit from the code. When a catch is created, a tag is specified, and executing a "throw" to this tag will exit from the body of code caught with this tag, and its value will be the value given in the call to "throw". If there is no such call, the code will be executed normally. Information pertaining to a catch is held in a struct catchtag, which is placed at the head of a linked list pointed to by "catchlist". internal_catch() is passed a C function to call (Fprogn() when Lisp "catch" is called) and arguments to give it, and places a catch around the function. Each struct catchtag is held in the stack frame of the internal_catch() instance that created the catch. internal_catch() is fairly straightforward. It stores into the struct catchtag the tag name and the current values of backtrace_list, lisp_eval_depth, gcprolist, and the offset into the specpdl array, sets a jump point with _setjmp() (storing the jump point into the struct catchtag), and calls the function. Control will return to internal_catch() either when the function exits normally or through a _longjmp() to this jump point. In the latter case, "throw" will store the value to be returned into the struct catchtag before jumping. When it's done, internal_catch() removes the struct catchtag from the catchlist and returns the proper value. Fthrow() goes up through the catchlist until it finds one with a matching tag. It then calls unbind_catch() to restore everything to what it was when the appropriate catch was set, stores the return value in the struct catchtag, and jumps (with _longjmp()) to its jump point. unbind_catch() removes all catches from the catchlist until it finds the correct one. Some of the catches might have been placed for error-trapping, and if so, the appropriate entries on the handlerlist must be removed (see "errors"). unbind_catch() also restores the values of gcprolist, backtrace_list, and lisp_eval, and calls unbind_to() to undo any specbindings created since the catch. 3c. other [fill in] ---------------------------------------------------------------------- -------------------------------- events ------------------------------ ---------------------------------------------------------------------- typedef enum emacs_event_type { empty_event, key_press_event, button_press_event, button_release_event, pointer_motion_event, process_event, timeout_event, magic_event, eval_event, menu_event, dead_event } emacs_event_type; #define first_event_type empty_event #define last_event_type dead_event struct key_data { int key; unsigned char modifiers; }; struct button_data { int button; unsigned char modifiers; int x, y; }; struct motion_data { int x, y; }; struct process_data { Lisp_Object process; }; struct timeout_data { Lisp_Object function; Lisp_Object object; int id_number; }; struct eval_data { Lisp_Object function; Lisp_Object object; }; #ifndef MAX_UNDERLYING_EVENT_SIZE # ifdef HAVE_X_WINDOWS # define MAX_UNDERLYING_EVENT_SIZE (sizeof (XEvent)) # else # define MAX_UNDERLYING_EVENT_SIZE 1 # endif #endif struct magic_data { char underlying_event [MAX_UNDERLYING_EVENT_SIZE]; }; struct Lisp_Event { emacs_event_type event_type; Lisp_Object channel; unsigned int timestamp; union { struct key_data key; struct button_data button; struct motion_data motion; struct process_data process; struct timeout_data timeout; struct eval_data eval; /* menu_event uses this too */ struct magic_data magic; } event; struct Lisp_Event *next; /* - For dead events, this is the next dead one. - For events on the command_event_queue, this is the next one on the queue. - Otherwise it's 0. */ }; struct event_stream { int (*event_pending_p) (int); void (*next_event_cb) (struct Lisp_Event *); void (*handle_magic_event_cb) (struct Lisp_Event *); int (*generate_wakeup_cb) (unsigned int, unsigned int, Lisp_Object, Lisp_Object); void (*disable_wakeup_cb) (int); void (*select_tty_cb) (int); void (*unselect_tty_cb) (int); void (*select_process_cb) (struct Lisp_Process *); void (*unselect_process_cb) (struct Lisp_Process *); #ifdef SIGIO void (*sigio_cb) (); #endif }; The event code is designed to be essentially system-independent. struct event_stream holds functions that interface between the generic event routines in Emacs and the specific window system, such as X. There is one instance, called "event_stream", of this structure. The event itself is held in struct Lisp_Event, which is filled in by the system-specific next_event_cb. 1. managing struct Lisp_Event's [event-alloc.c] allocate-event, deallocate-event, and copy-event are in event-alloc.c; see its description. This module also contains some routines used during garbage-collection. 2. converting event types [events.c] character_to_event(), event_to_character(), event-to-character, and character-to-event convert between ASCII characters and keypresses corresponding to the characters. If the event was not a keypress, event_to_character() returns -1 and event-to-character returns NIL. These functions convert between ASCII representation and the split-up event representation (keysym plus mod keys). format_event_object() takes an event of any type and returns a short string describing to this event. (e.g. M-C-x for a keypress of meta-control-X). 3. event predicates eventp, key-press-event-p, button-press-event-p, button-release-event-p, button-event-p, motion-event-p, process-event-p, timeout-event-p, menu-event-p, and eval-event-p are fairly self-explanatory. 4. event properties event-timestamp, event-key, event-button, event-modifier-bits, event-modifiers, event-x-pixel, event-y-pixel, event-window, event-point, event-x, event-y, event-glyph, event-process, event-function, and event-object are fairly clear. Some of these routines call event_pixel_translation(), which takes a motion or button event and returns the window, x and y character position, buffer, and glyph over which the event occurred [what is a glyph?]. The work is actually done by pixel_to_glyph_translation (see "display"). event_equal(), used by equal, compares two events. 5. obtaining events NOTE: I am not sure whether the routines below ever get executed asynchronously. If so, life gets messy. next-event fills in a struct Lisp_Event with an event. The event comes from one of three places: 1) unread-command-event, if not NIL (copied with copy-event) 2) a keyboard macro, if we're in one (pop_kbd_macro_event()) 3) next_event_internal() Before getting an event, next-event refreshes the screen (redisplay()) if there is no event pending (detect_input_pending()). After getting an event, next-event does various processing: 1) maybe_status_notify() is called. 2) for key-presses, maybe_do_auto_save() is called. 3) for key-presses and button events, things are set up so that the event will be echoed in the echo area after a fixed amount of time. 4) for "command events" (key-presses, button actions, and menu selections), [V]last-input-event, [V]last-input-char, [V]last-input-time, [V]this-command-keys (visible as Lisp function this-command-keys), and recent_keys_ring (visible as Lisp function recent-keys-ring) are updated/ If we're defining a keyboard macro, the macros is updated. 5) if the help key was pressed (variable "help_char"), execute_help_form() is called. next_event_internal() obtains an event either from the command_event_queue or, if this is empty, by calling next_event_cb. (The queue is linked through the "next" field of struct Lisp_Event; events are placed on the queue by enqueue_command_event(), which is called by some functions that read events, filter some of them out, and put the remaining ones back.) next_event_internal() also checks if the event was a keypress of interrupt_char (defined to be ^G in keyboard.c), and calls interrupt_signal() if so. detect_input_pending() and input-pending-p look for input by calling event_stream->event_pending_p and looking in [V]unread-command-event and the command_event_queue (they do not check for an executing keyboard macro, though). discard-input cancels any command events pending (and any keyboard macros currently executing), and puts the others onto the command_event_queue. There is a comment about a "race condition", which is not a good sign. next-command-event and read-char are higher-level interfaces to next-event. next-command-event gets the next "command" event (i.e. keypress, mouse event, or menu selection), calling dispatch-event on any others. read-char calls next-command-event and uses event_to_character() to return the ASCII equivalent. accept-process-output??? 6, 7, ... [more event stuff] ---------------------------------------------------------------------- ---------------------- execution of Lisp code ------------------------ ---------------------------------------------------------------------- Main data structures during Lisp execution: 1. staticvec[]: lists all global and static C variables that hold Lisp objects. Used during garbage collection. See "allocation". gcprolist, specpdl, and backtrace_list are stacks that are added to and removed from as Lisp and C functions are entered and exited. 2. gcprolist: points to a linked list of struct gcpro's, listing currently-active C local variables that hold Lisp objects. Each struct gcpro is located in the same stack frame as the local variable it references. Used during garbage collection. See "allocation". 3. specpdl: points to an array of struct specbinding's, each of which references a currently-active Lisp local binding or a currently-active unwind-protect. See "eval". 4. backtrace_list: points to a linked list of struct backtrace's, each of which gives information about a Lisp function call currently executing. Each struct backtrace is located in the stack frame of the Feval() or Ffuncall() instance that initiated the function call. See "eval". 5. Vobarray: holds the obarray, which lists all symbols that have been interned. The obarray is a vector of linked lists arranged as a separately-chained hash table. See "obarray". 6. catchlist: points to a linked list of struct catchtag's, each of which specifies a catch that is currently active. Each struct catchtag is located in the stack frame of the instance of internal_catch(), Fcondition_case(), or internal_condition_case() that created the catch. See "eval -- special forms". 7. handlerlist: points to a linked list of struct handler's, each of which corresponds to a condition-case that is currently active. Each struct handler is located in the stack frame of the instance of Fcondition_case() or internal_condition_case() that created the condition-case. See "errors". ---------------------------------------------------------------------- ------------------------------ Extents ------------------------------- ---------------------------------------------------------------------- [extents.c] [extents.h] An "extent" is a region of text with a certain property, such as invisible, read-only, or highlighted. Extents can overlap, and the text under overlapping extents has all the properties of the extents lying over that text. [what if some properties contradict each other?] 1. structures typedef struct { int seal; /* must be EXTENT_SEAL */ Id id; int extentType; /* oneof CEAttribute, CEAbbreviation, etc. */ Lisp_Object extent; /* corresponding extent */ #ifdef ENERGIZE Lisp_Object start_glyph_index; Lisp_Object end_glyph_index; #endif union { struct { /* CEAttribute */ int attrValue; } attr; struct { /* CEAbbreviation */ Boolean isOpened; } abbrev; struct { /* CEGeneric */ GenericData* gData; } generic; } u; } Extent_Data; 1a. struct extent struct extent { unsigned short flags; /* non-zero only for "extended type extents" */ unsigned short secondary_type; int start; int end; struct extent *next; struct extent *previous; struct extent *e_next; struct extent *e_previous; int attr_index; Lisp_Object buffer; Lisp_Object user_data; }; "start", "end" are the limits of the extent. "buffer" is the buffer this extent refers to. "flags" is the properties of the extent, defined in extents.h. "next", "previous", "e_next", and "e_previous" are used to link all the extents together. Extents are linked in two bidirectional linked lists -- one ordered by start position ("next", "previous") and the other by end position ("e_next", "e_previous"). "user_data" is any extra data that the user might choose to associate with an extent. attr_index? secondary_type? typedef struct extent *EXTENT; 1b. extent indices The start and end positions of an extent are simple character indices. This is not necessarily the same as the buffer index, because the latter takes the gap into account. (see "buffer") buffer_pos_to_extent_index(pos, buf) extent_index_to_buffer_pos(index, pos) These functions perform the conversion between buffer indices and extent indices. 1c. extent lists Extents are linked in two bi-directional linked lists. The orderings for these two lists are called "display" or "normal" order and "e-order", which are essentially sorting by start and end positions, respectively. splice_extent_into_buffer(extent, buffer) Inserts an extent into the linked lists. detach_extent() Removes an extent from the linked lists and sets its start and end positions to 0. next-extent next-e-extent Returns the next extent in the specified list. 1. creating an extent Extents are managed just like cons cells -- see "allocation". make_extent(void) [alloc.c] Allocates and returns a new extent. make-extent Creates a new extent; calls make_extent_internal(). make_extent_internal(from, to, buffer, extent_data) Allocates an extent, sets the position of the extent, and inserts it into the buffer's extent lists. delete-extent Destroys an extent; calls destroy_extent() and sets some flags indicating that the buffer's display has changed. destroy_extent() Removes an extent from the buffer's extent lists and clears its values. It will be reclaimed during garbage collection. 3. extent properties EF_* Masks referring to particular properties in the extent's "flags" field. SET_EXTENT_FLAG() CLEAR_EXTENT_FLAG() EXTENT_FLAG_P() Macros that get or set particular properties in the "flags" field. extent-start-position extent-end-position extent-length extent-buffer Return the respective properties of an extent. update-extent Change the start and end positions of an extent. This detaches the extent, sets the positions, and inserts the extent back into the buffer's extent lists. update_extent() Does the same thing as update-extent, but has separate code. extent-attributes set-extent-attribute Get or set the attributes (invisible, highlighted, etc.) of an extent. extent-data set-extent-data get or set the user data for an extent. 4. mapping over extent lists typedef int (*emf)(EXTENT extent, void *arg); typedef int (*elisp_emf)(Lisp_Object extent_obj, void *arg); struct slow_map_extents_arg { Lisp_Object map_arg; Lisp_Object map_routine; }; map-extents Calls a function on all extents overlapping a specified range. map_extents() is called and given as its function either the specified function (if it's a built-in subr) or slow_map_extents_function (if the specified function is a user function). map_extents() Calls a function on all extents overlapping a specified range. It marches down the display-order list of extents and checks each one to see if the range matches. The function is called with two arguments -- the extent itself and a user-supplied value. slow_map_extents_function() Function given to map_extents() so that user-defined Lisp functions can be mapped. The second argument given to it is a struct slow_map_extents_arg, containing the Lisp function and the actual argument to be given to it. call2() is used to call the function. 5. determine the smallest enclosing extent for a position struct extent_at_struct { EXTENT best_match; int flag; }; extent-at Determines the smallest extent overlapping a specified position and having the specified properties. Calls extent_at(). extent_at() Does the actual work. Maps the function extent_at_mf() over all extents. The argument given is of type struct extent_at_struct. extent_at_mf() The map function used by extent_at(). Checks the extent to see if it's a candidate and is smaller than the smallest one found so far. 6. highlighting an extnt The display code looks in [V]last-highlighted-extent to determine which extent should be highlighted. extent_highlightable_p() True if an extent has the "highlightable" property. do_highlight() Highlight or unhighlight an extent. This involves changing [V]last-highlighted-extent and setting some flags indicating that the buffer has changed. highlight-extent Highlight an extent if it has the "highlightable" property. Calls do_highlight(). force-highlight-extent Highlight an extent always. Calls do_highlight(). 7. Dealing with textual change The range of an extent is adjusted when text is inserted or deleted. In addition, some extents must be deleted entirely. [extents.c] /* not used at the moment */ struct process_extents_for_insertion_struct { int opoint; int length; struct buffer *buf; }; struct process_extents_for_deletion_struct { int start; int end; int destroy_included_extents; }; adjust_extent_index() adjust_extents() process_extents_for_insertion() process_extents_for_deletion_mf() process_extents_for_deletion() process_extents_for_destruction() 8. checking the read-only property of a range of extent verify_extent_modification() is called by prepare_to_modify_buffer() in insdel.c, and makes sure that none of the region about to be modified is read-only. struct end_points { int start; int end; }; verify_extent_modification(buffer, from, to) Make sure none of the text in the specified range is read-only. Maps verify_extent_mf() over all extents. The argument given to this function is of type struct end_points. verify_extent_mf() Called by map_extents(). Signals an error if the specified extent is read-only and overlaps the specified range of text. 9. extent fragments An "extent fragment" is a structure holding all of the extents overlapping a particular position, as well as the range of positions around the specified position which have exactly the same extents overlapping them (i.e. the maximum range containing this position in which no extents begin or end). All characters in this range have exactly the same properties. [extents.h] struct extent_fragment { /* buffer and modification event of buffer for this fragment */ struct buffer *buf; int modiff; int face_change; /* covers buffer positions [from, to-1] */ int from; int to; /* these are the buffer array indices of positions from and to */ int start_index; int end_index; /* first extent past the stack */ EXTENT first_extent_past_stack; int number_of_extents; EXTENT *extents_stack; int extents_stack_length; struct face *fp; }; typedef struct extent_fragment *EXTENT_FRAGMENT; struct extent_fragment extent_fragment; int extent_cache_invalid; "buf" is the buffer this extent fragment refers to, and "modiff" and "face_change" hold the values of these buffer fields when the extent fragment was created. "from" and "to" are the range in buffer indices, and "start_index" and "end_index" the corresponding range in extent indices (i.e. the former range takes into account the gap). "extents_stack" is the array of extents overlapping the range, and "number_of_extents" the number of extents in this array. "extents_stack_length" is the actual size of the array, which is >= number_of_extents (the array is realloc()ed as necessary to accommodate more extents). "first_extent_past_stack" is the first extent whose start position is past the end of the range. The global variable "extent_fragment" is of type struct extent_fragment and is used by the extent fragment routines. init_extent_fragment(void) Initializes the variable "extent_fragment". buffer_extent_fragment_at(pos, buffer, screen) Determines the extent fragment surrounding the specified position. It first checks if the previously-calculated extent fragment is still valid (by looking at "extent_cache_invalid" and the values of MODIFF and FACE_CHANGE stored in the variable "extent_fragment", among other things), and only does the recalculation (by calling befa_internal()) if not. A pointer to "extent_fragment" is returned. internal_befa(pos, buffer) Actually calculates the extent fragment. Returns a pointer to "extent_fragment". 10. stack of extents Every buffer has a "stack of extents", which is used to speed up traversing through the extents, looking for extents that overlap a particular range. The stack of extents is used by buffer_starting_extent(), which returns an extent that you can start such a traversal at. The stack of extents is stored in a buffer's "cached_stack" field and is held in a "struct stack_of_extents". This structure contains a buffer position, an array of all the extents that overlap the position, and the "previous" extent, which is the last extent (in display order) that does not overlap the position and which comes before (in display order) all the extents that do. The code to manipulate a stack of extents is hairy and involved, and there are lots of comments in extents.c. /* sort of a mini-version of the extents fragment -- each buffer with an extents list gets one of these */ struct stack_of_extents { /* an extent "before" those on the stack, or 0 if none is known */ EXTENT previous_extent; /* buf_index over which this stack lies */ int buf_index; EXTENT *stack; int stack_length; int stack_index; }; soe_to_lisp() stack-of-extents verify_buffer_stack() soe_push() soe_duplicate() soe_delq() init_buffer_cached_stack() soe_clear() soe_prune() free_buffer_cached_stack() cleanup_old_stack() update_cache_forward() 11. extent replicas [I think] Extent replicas are used when text is cut or copied from a buffer. the extents that overlap the text are copied into extent replicas that are attached to the text. [extents.h] struct extent_replica { int start; int end; Lisp_Object extent; }; typedef struct extent_replica *EXTENT_REPLICA; typedef struct extent_replica *DUP; struct merge_replicas_struct { Lisp_Object dup_list; int entry_offset; int entry_length; }; [extents.c] struct replicate_extents_struct { int from; int length; struct buffer *buf; Lisp_Object head; Lisp_Object nconc_cell; }; replicate_extents_mf() replicate_extents() splice_in_extent_replicas() merge_replicas() add_to_replicas_lists() merge_replicas_concatenating_mf() mrp_pred() merge_replicas_pruning_mf() x. miscellaneous check_from_to(from, to, buf) Make sure that positions "from" and "to" lie within the buffer "buf". extent_endpoint(extent, endp) Returns the start or end point of the specified extent, as a *buffer* index. extent_index_offset() buffer_starting_extent() syms_of_extents() y. not yet dealt with set_extent_flags() set_extent_attributes_index() install_extent_glyphs() restore_extent_state() extent_to_generic_id() make_extent_for_data() extent_glyph_at() extent-to-generic-id glyph_in_column_p() restore-extent set_point_internal() set_point() set_buffer_point() last_visible_position() ---------------------------------------------------------------------- ------------------------------- Faces -------------------------------- ---------------------------------------------------------------------- struct face { unsigned char underline; unsigned char hilited; unsigned char modif; #ifdef HAVE_X_WINDOWS GC facegc; XFontStruct* font; #if 0 char* font_name; /* missing piece of info from XFontStruct... */ #endif /* we store this up in lisp now */ unsigned long foreground; unsigned long background; Pixmap back_pixmap; unsigned int pixmap_w, pixmap_h, pixmap_depth; #endif /* HAVE_X_WINDOWS */ }; About faces: A face is represented on the Lisp level as an array of 8 elements, the first of which is the symbol 'face: element: meaning: 0 'face 1 name of face 2 face id number 3 name of face's font or nil 4 name of foreground color 5 name of background color 6 name of background pixmap 7 whether face is underlined In the C code, faces are stored as a struct face: struct face { unsigned char underline; unsigned char hilited; unsigned char modif; unsigned char fill_style; struct font *font; unsigned long foreground; unsigned long background; struct x_bitmap *back_pixmap; }; Every screen contains an alist of all the faces, associating the face's name with its representation as a Lisp vector. In addition, each screen contains an array of pointers to struct face's, one per face, indexed by the face's id number. Note that the Lisp data shadows the C data and that each screen contains a separate copy of all the faces; this is so that faces of the same name (e.g. "default" or "modeline") can display differently for different screens. In struct screen, "face_alist" is the screen's alist of faces, "faces" is the array of pointers to struct face's, and "n_faces" is the number of elements in the array. make-face creates a new face with a specified name, setting its name and id number and leaving its other attributes unspecified. It modifies the face-alist of all the screens and calls make-face-internal to create the struct face's and modify the C pointers. Individual characteristics of a face are modified with set-face-font, set-face-foreground, set-face-background, set-face-background-pixmap, and set-face-underline. All of these allow modifying the characteristic of the face only on one screen or on all screens. All call set-face-1, which modifies the Lisp faces appropriately and calls set-face-attribute-internal to change the C structures. This function calls load_pixmap(), load_font(), load_color(), etc. as necessary. Individual characteristics of a face are retrieved with face-name, face-id, face-font, face-foreground, face-background, face-background-pixmap, and face-underline-p. ---------------------------------------------------------------------- ------------------------------ Fonts --------------------------------- ---------------------------------------------------------------------- The font type is XFontStruct. #define FONT_WIDTH(f) ((f)->max_bounds.width) #define FONT_HEIGHT(f) ((f)->ascent + (f)->descent) #define TOTAL_HEIGHT(f) ((f)->ascent + (f)->descent + x_interline_space) #define FONT_BASE(f) ((f)->ascent) FONT_ASCENT(f) [xdisp.c] is equivalent to FONT_BASE(f). x_interline_space is the space in pixels to be placed between lines. The baseline is the line on which all characters are to be placed. Some characters extend below the baseline as well as above it (e.g. lowercase g). The "ascent" is the number of pixels the character extends above the baseline, and the "descent" the number of pixels the character extends below the baseline. These two values vary from character to character. The default font for a screen is contained in screen->display.x->font. ---------------------------------------------------------------------- -------------------------- Fundamental Types ------------------------- ---------------------------------------------------------------------- Lisp_Object is the main type. This is just a 32-bit int, of which the lowest 24 (or 26) bits are the value of the type (either an integer or a pointer to the type's actual value), the remaining bits except 1 specify the type, and the highest bit is a garbage-collection bit that is always 0 when not in garbage-collection. Accessing the value of a Lisp_Object as a particular type is done through the macros in lisp.h, which are all in capital letters without any underscores, and begin with X (e.g. XINT(), XSYMBOL(), etc.). These macros mask off the type bits and cast the value to the correct integer or pointer type. The types (enum Lisp_Type) are: Lisp_Int Integer. XINT(obj) is the integer value. Lisp_Symbol Symbol. XSYMBOL (object) points to a struct Lisp_Symbol. Lisp_Marker Marker (buffer ptr). XMARKER(object) points to a struct Lisp_Marker. Lisp_String String. XSTRING (object) points to a struct Lisp_String. The length of the string, and its contents, are stored therein. Lisp_Vector Vector of Lisp objects. XVECTOR(object) points to a struct Lisp_Vector. The length of the vector, and its contents, are stored therein. Lisp_Cons Cons. XCONS (object) points to a struct Lisp_Cons. Lisp_Compiled Byte-compiled function. A vector of 4 to 6 elements which are the arglist, bytecode-string, constant vector, stack size, (optional) doc string, and (optional) interactive spec. Lisp_Buffer Editor buffer. XBUFFER(obj) points to a struct buffer. Lisp_Subr Built-in function. XSUBR(obj) points to a struct Lisp_Subr which describes how to call the function, and its documentation, as well as pointing to the code. Lisp_Internal Internal value return by subroutines of read. The user never sees this data type. Its value is just a number. Lisp_Intfwd Forwarding pointer to an int variable. This is allowed only in the value cell of a symbol, and it means that the symbol's value really lives in the specified int variable. XINTPTR(obj) points to the int variable. Lisp_Boolfwd Boolean forwarding pointer to an int variable. This is like Lisp_Intfwd except that the ostensible "value" of the symbol is t if the int variable is nonzero, nil if it is zero. XINTPTR(obj) points to the int variable. Lisp_Process Object describing a connection to a subprocess. It points to storage of type struct Lisp_Process. Lisp_Objfwd Forwarding pointer to a Lisp_Object variable. This is allowed only in the value cell of a symbol, and it means that the symbol's value really lives in the specified variable. XOBJFWD(obj) points to the Lisp_Object variable. Lisp_Screen Pointer to a vector-like object describing a display screen on which Emacs can display a window hierarchy. Lisp_Internal_Stream Used when a FILE * value needs to be passed in an argument of type Lisp_Object. You must do *(FILE **) XPNTR(obj) to get the value. The user will never see this data type. Lisp_Buffer_Local_Value Used in a symbol value cell when the symbol's value is per-buffer. The actual contents are a cons cell which starts a list like this: (REALVALUE BUFFER CURRENT-ALIST-ELEMENT . DEFAULT-VALUE)). BUFFER is the last buffer for which this symbol's value was made up to date. CURRENT-ALIST-ELEMENT is a pointer to an element of BUFFER's b_local_var_alist, that being the element whose car is this variable. Or it can be a pointer to the (CURRENT-ALIST-ELEMENT .DEFAULT-VALUE), if BUFFER does not have an element in its alist for this variable (that is, if BUFFER sees the default value of this variable). If we want to examine or set the value and BUFFER is current, we just examine or set REALVALUE. If BUFFER is not current, we store the current REALVALUE value into CURRENT-ALIST-ELEMENT, then find the appropriate alist element for the buffer now current and set up CURRENT-ALIST-ELEMENT. Then we set REALVALUE out of that element, and store into BUFFER. If we are setting the variable and the current buffer does not have an alist entry for this variable, an alist entry is created. Note that REALVALUE can be a forwarding pointer. Each time it is examined or set, forwarding must be done. Lisp_Some_Buffer_Local_Value Like Lisp_Buffer_Local_Value with one difference: merely setting the variable while some buffer is current does not cause that buffer to have its own local value of this variable. Only make-local-variable does that. Lisp_Buffer_Objfwd Like Lisp_Objfwd except that value lives in a slot in the current buffer. Value is byte index of slot within buffer Lisp_Void In symbol value cell, means var is unbound. In symbol function cell, means function name is undefined. Lisp_Window Window used for Emacs display. Data inside looks like a Lisp_Vector. Lisp_Window_Configuration Used by save,set,restore-window-configuration Lisp_Extent An active region in buffer or string. XEXTENT (obj) is typedef EXTENT. Lisp_Extent_Data Lisp_Extent_Replica Lisp_Float Lisp_Event Lisp_Keymap Lisp objects are created through various functions, some of which just mirror just mirror Lisp primitives. make_number() converts a number into a Lisp_object, without allocating any space. Fmake_vector() creates a vector of a specified size. ---------------------------------------------------------------------- ------------------------------- glyphs ------------------------------- ---------------------------------------------------------------------- [dispnew.c, xdisp.c] A "glyph" is (more or less) a single character to be displayed on the screen. Note that a character in the text may be displayed as more than one glyph (e.g. "^L" is normally displayed as two glyphs, ^ and L.) Internally, a glyph is of type GLYPH, which is actually a 16-bit value but normally just holds a regular character. 1. structures /* This structure is used for the actual display of text on a screen. There are two instantiations of it: the glyphs currently displayed, and the glyphs we desire to display. The latter object is generated from buffers being displayed. */ struct screen_glyphs { #ifdef MULTI_SCREEN struct screen *screen; /* Screen these glyphs belong to. */ #endif /* MULTI_SCREEN */ int height; int width; int *used; /* Vector of widths (in chars) of lines. */ GLYPH **glyphs; /* glyphs[Y][X] is the GLYPH at X,Y. */ GLYPH *total_contents; /* The actual contents. `glyphs' points here */ char *enable; /* Vector indicating meaningful contents. */ int *bufp; /* Buffer offset of this line's first char. */ int *nruns; /* N runs of differently displayed text. */ struct run **face_list; struct run *faces; #ifdef HAVE_X_WINDOWS short *top_left_x; /* Pixel position of top left corner */ short *top_left_y; short *pix_width; /* Pixel width of line. */ short *pix_height; /* Pixel height of line. */ short *max_ascent; /* Pixel value of max font->ascent of line. */ #endif /* HAVE_X_WINDOWS */ }; "struct screen_glyphs" is a complete description of what is currently displayed on a screen. The text is stored as a two-dimensional array of glyphs along with a series of "runs" describing how the text is to be displayed. Each line has a number of such runs, and each run describes how a particular chunk of text is to be displayed (i.e. if there is a font change on a line, a new run will start there). "screen" is the screen this structure refers to, and "height" and "width" are the size of the screen in glyphs. "pix_height" and "pix_width" are arrays specifying the height and width of each line in pixels. (note that "pix_height" includes the interline space) "max_ascent" is an array specifying the maximum ascent of each line, in pixels -- i.e. the maximum height the line extends above its baseline (each character is made up of an ascent and a descent, and the total height of the character is determined by adding these two values plus the interline space). "used" is an array specifying, for each line, the number of text characters (not glyphs) on that line. "glyphs" is an array of vectors, each describing the glyphs on a line. The vectors themselves are stored contiguously in "total_contents". Note that at the end of each line of glyphs there is a NULL_GLYPH. "nruns" is an array specifying the number of runs on each line. "face_list" is an array of vectors, each listing the runs on a line. "enable" is an array specifying, for each line, whether the glyph contents of that line are valid. For the "current glyphs" structure, this array is reset when screen lines become garbaged. For the "desired glyphs" structure, this is reset when the structure is cleared out prior to redisplay. "top_left_x" and "top_left_y" are arrays specifying, for each line, the pixel coordinate of the top left corner of the line. 0. validating/invalidating lines of text cancel_line(vpos, screen) Invalidate the specified line. This resets the enable[] value in the screen's desired glyphs. clear_screen_records(screen) Invalidate all the lines in the screen's current glyphs. 1. converting text characters to glyphs; display tables struct glyphs_from_chars { UCHAR c; GLYPH *glyphs; #ifdef LINE_INFO_COLUMN Lisp_Object info_column_glyphs; #endif int columns; struct face *faceptr; Lisp_Object begin_class[GLYPH_CLASS_VECTOR_SIZE]; Lisp_Object end_class[GLYPH_CLASS_VECTOR_SIZE]; short n_nonfont; int next_visible; UCHAR begin_or_end; /* 0:none, 1:end, 2:begin, 3:both */ #ifdef HAVE_X_WINDOWS int begin_columns; int begin_pixel_width; int end_columns; int end_pixel_width; int pixel_width; int pixel_height; #endif /* The chars in the buffer being processed that lie between [run_pos_lower, run_pos_upper] are promised to be in the same run, and to be separated from begin and/or end glyphs, provided they fit on the same line. This means that there are NO pixel-maps (sometimes called glyphs in other contexts) or font changes in the display of the chars in this range. It is NOT promised to be a maximal such range. */ int run_pos_lower; int run_pos_upper; }; The "display table" controls the way characters are displayed. There is a default display table, [V]standard-display-table, and "display_table" is a built-in buffer-local field in struct buffer. A display table is a Lisp vector of 261 elements. The first 256 correspond to all possible characters, and the last 5 refer to special characters (the "control glyph" for displaying control characters, the "escape glyph" when characters are displayed in octal, the "continuation glyph" for long lines, etc.) -- see buffer.c, "buffer-display-table". Each element is a "rope", which is a string that is interpreted to be an array of glyphs, i.e. a double-character string. If an element of the display table is NIL, a default interpretation is substituted. The built-in buffer-local variable "ctl-arrow" controls how the default is printed. The defaults are: 1) printable characters, and characters deemed to be printable through ctl-arrow: the character itself. 2) control characters, if ctl-arrow is not nil: the "control glyph" followed by a printable glyph for the character. 3) tab: the correct number of instances of TABGLYPH, which is defined to be '\t'. (note that this substitution *always* happens; i.e. the rope for "tab" sitting in the display table is ignored.) 4) other characters: the "escape glyph" followed by the octal representation of the character. 5) the control glyph: ^. 6) the escape glyph: \. struct glyphs_from_chars is used to hold the glyphs corresponding to a string of characters. Some of the functions below return a pointer to such a structure. They use a static variable "char_glyphs". GLYPH_SET_VALUE(g, v) Macro to set a glyph's value. Just does "g = v". GLYPH_FROM_CHAR(c) Converts a character to a glyph. Just does (GLYPH) c. struct glyphs_from_chars * glyphs_from_char(screen, c, g, tab_width, ctl_arrow, fp, dp, hscroll, columns, tab_offset, pixel_values) Determines and returns the glyphs that correspond to a text character "c". The glyphs are returned through "g", a pointer to an array of glyphs. Also returns a pointer to "char_glyphs", which contains this same information plus values in the fields "columns", "pixel_width", and "pixel_height". See above description of glyphs for a description of how this actually works. update_cache(buffer, extfrag) Used by glyphs_from_bufpos() to cache the information last returned from buffer_extent_fragment_at(). struct glyphs_from_chars * glyphs_from_bufpos (screen, buffer, pos, dp, hscroll, columns, tab_offset, direction, only_nonchars) Similar to glyphs_from_char() but also deals with "begin glyphs" and "end glyphs". (used only when XEmacs is linked with Energize) This requires looking at the extent fragment for the specified position. Calculating an extent fragment is an expensive operation, so the last-calculated extent fragment is cached in case it's still valid. (However, buffer_extent_fragment_at(), which is called to compute the extent fragment, does its own caching, so the caching done here is worthless.) "last_buffer", "last_screen", "last_buffer_modiff", "last_buffer_facechange", "last_buffer_extfrag", "last_extfrag_from_pos", "last_extfrag_to_pos", and "last_extfrag_face" are used to do the cachine. Some code is duplicated between this function and glyphs_from_chars(). Instead of using a user-supplied glyph array, the static variable "measure_glyphs" is used. A pointer to the static variable "displayed_glyphs" is returned. 2. begin and end glyphs I'm not sure what these are, but they only seem to exist when XEmacs is linked with Energize. Some day I may figure out what they are and see if they're neat feature, but not now. Suffice to say, if ENERGIZE is not defined there will never be any. 3. runs enum run_type { unused_run, glyph, column_glyph, font, space, window /* indicate a window change */ }; The run types are as follows: unused_glyph: glyph: a bitmap. column_glyph: font: characters to be displayed in a particular font. space: window: struct run { enum run_type type; int length; /* Length in glyphs */ struct face *faceptr; struct window* w; /* window starting here */ int bufp; /* position in buffer */ Lisp_Object class; /* extent containing, if any */ int begin_p; /* 1 begin glyph 0 if end glyph*/ #ifdef HAVE_X_WINDOWS int pix_length; /* Length in pixels */ #endif #ifdef LINE_INFO_COLUMN int lineinfo_glyph_index; /* Since glyphs in the lineinfo column don't go into the glyphs array (because they don't take up screen space) we need to store them somewhere. */ #endif }; A "run" is a part of a line of text that is to be displayed with a particular characteristic. If different parts of a line of text are to be displayed with different characteristics, these different parts will be described with different runs. Runs are stored within a struct screen_glyphs, as described above. "struct run" specifies a run. "type" is the type of run, "length" the number of glyphs in the run, "faceptr" the characteristics of the text to be displayed, "w" the window in which the run occurs [check this??]. int new_run(screen, vpos, type, faceptr) Adds a new run to the screen's "desired_glyphs" structure. "vpos" is the line on which the run occurs, and "type" and "faceptr" are the run's characteristics. Returns the index of this run in the vector of runs for this line. struct run *append_run(screen, vpos, type, class, faceptr, begin_p) Similar to new_run(). In addition, sets the run's "class" and "begin_p" values. Return value is different. void right_shift_runs(screen, vpos, run, nslots) Right-shift the lines on line "vpos" in the screen's "desired_glyphs" structure by "nslots" runs, starting at run "run". The new slots are not initialized. SET_RUN(screen, vpos, run, type, len, face, class, begin_p, pix_length) Initializes a run with the specified values. 4. updating the glyphs in struct screen_glyphs void append_glyph(screen, vpos, glyph, type, class, faceptr, begin_p) Adds a glyph to the screen's "desired_glyphs" structure, at the end of the line "vpos". "type", "class" and "faceptr" specify the characteristics of this glyph; if the last run on the specified line does not match these characteristics, a new run is created. The various arrays are updated as necessary. void remove_glyph(screen, vpos) Removes the last glyph on line "vpos" in the screen's "desired_glyphs" structure. If this causes the last run to shrink to zero glyphs in length, the run is removed. All structures are updated as necessary except pix_height[]. void overlay_glyph(screen, vpos, glyph, type, class, faceptr, column, begin_p) Overlays the glyph at column "column" on line "vpos" in the screen's "desired_glyphs" structure. "type", "class" and "faceptr" specify the characteristics of this glyph; if the run at the specified position does not match, that run is split as necessary and a new run inserted as necessary. (Note that the code does not currently handle the case where a run must be split in the middle) All structures are updated as necessary except pix_height[]. May call right_shift_runs() to insert a run. int display_string(w, vpos, string, hpos, truncate, mincol, maxcol, this_face, pix_width_ptr) /* Display NULL-terminated STRING on one line of window W, starting at HPOS. Display at position VPOS. Caller should have done get_display_line. TRUNCATE is GLYPH to display at end if truncated. Zero for none. MINCOL is the first column ok to end at. (Pad with spaces to this col.) MAXCOL is the last column ok to end at. Truncate here. -1 for MINCOL or MAXCOL means no explicit minimum or maximum. Both count from the left edge of the screen, as does HPOS. The right edge of W is an implicit maximum. If TRUNCATE is nonzero, the implicit maximum is one column before the edge. Display is performed using FACE, unless that is 0, then the screen default face is used. Each new string on the smae line consitutes a different run. Returns ending hpos on the line. If PIX_WIDTH_PTR is nonzero, it is a pointer to an int variable that will be set to the pixel width of the string. */ Changes the "desired_glyphs" structure of the window's screen. Pads as necessary with spaces to reach position "hpos"; then overlays or appends the glyphs, using overlay_glyph() or append_glyph(). glyphs_from_char() is first called to convert a character to one or more glyphs; the standard display table [V]standard-display-table is used for this purpose. [why???] If the string needs to be truncated, any extra glyphs that got added beyond the end are removed and the glyph "TRUNCATOR_BITMAP" is added. If necessary, the end is padded with spaces. 5. displaying the mode line decode_mode_spec() display_mode_element() display_mode_line() 6. displaying the title screen_title_display_string() x_format_screen_title() 9. other utility routines run_from_glyph_index() get_glyph_dimensions() add_in_column_glyph() int pixel_to_glyph_translation(struct screen *s, unsigned int pix_x, unsigned int pix_y, int *x, int *y, struct window **w, int *bufp, int *gly, Lisp_Object *class, int *begin_p) Determine the glyph under the pixel (pix_x, pix_y) on the screen "s". The glyph itself is returned in "gly", its coordinates in (x, y), the window containing these coordinates in "w", ... 10. misc init_xdisp() syms_of_xdisp() ---------------------------------------------------------------------- --------------------------- input blocking --------------------------- ---------------------------------------------------------------------- what the hell is this? This is found in free-hooks.c. BLOCK_INPUT(), UNBLOCK_INPUT(), and other such macros are called all over the place. ---------------------------------------------------------------------- ------------------------------ main loop ----------------------------- ---------------------------------------------------------------------- The main loop is recursive-edit, which is called by main() and in various other places. recursive-edit and the functions below it do lots of unwind-protecting, condition-casing, and catching because of the possibility of a non-local exit from recursive-edit (see flowchart). If we are at the top level and "top-level" contains a Lisp form, it is executed (this is set by loadup.el, which is normally run from the command line when the original bare Emacs is converted to the full version). Normally "normal-top-level" (in startup.el) is called, and processes the command line and does other such stuff. command_loop_1() is then called, and it is the real main loop. All it does is loop until ^G is hit (or until a sub-function causes a non-local exit), getting an event and dispatching it. ---------------------------------------------------------------------- -------------------------------- menus ------------------------------- ---------------------------------------------------------------------- A menu is set by setting the value of the variable "current-menubar" (which may be buffer-local) and then calling "set-menubar-dirty_flag" to signal a change. This will cause the menu to be redrawn at the next redisplay. The format of the data in "current-menubar" is described in menubar.c. Internally the data in current-menubar is parsed into a tree of widget_value's (defined in lwlib.h); this is accomplished by the recursive function menu_item_descriptor_to_widget_value(), called by compute_menubar_data(). Such a tree is deallocated using free_widget_value(). update_screen_menubars() is one of the external entry points. This checks to see, for each screen, if that screen's menubar needs to be updated. This is the case if 1) set-menubar-dirty-flag was called since the last redisplay. (This function sets the C variable menubar_has_changed.) 2) The buffer displayed in the screen has changed. 3) The screen has no menubar currently displayed. set_screen_menubar() is called for each such screen. This function calls compute_menubar_data() to create the tree of widget_value's, then calls lw_create_widget(), lw_modify_all_widgets(), and/or lw_destroy_all_widgets() to create the X-Toolkit widget associated with the menu. update_psheets(), the other external entry point, actually changes the menus being displayed. It uses the widgets fixed by update_screen_menubars() and calls various X functions to ensure that the menus are displayed properly. The menubar widget is set up so that pre_activate_callback() is called when the menu is first selected (i.e. mouse button goes down), and menubar_selection_callback() is called when an item is selected. pre_activate_callback() calls the function in activate-menubar-hook, which can change the menubar (this is described in menubar.c). If the menubar is changed, set_screen_menubars() is called. menubar_selection_callback() enqueues a menu event, putting in it a function to call (either "eval" or "call-interactively") and its argument, which is the callback function or form given in the menu's description. ---------------------------------------------------------------------- ----------------------------- minibuffers ---------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- ---------------------------- naming scheme --------------------------- ---------------------------------------------------------------------- 'F...' C functions corresponding to Lisp primitives 'S...' struct Lisp_Subr's corresponding to Lisp primitives 'V...' C variables tied to built-in Lisp variables 'Q...' C structures corresponding to Lisp constants, such as Qt and Qnil 'QK..' C variables holding Lisp_Objects containing keysym names ---------------------------------------------------------------------- --------------------- naming scheme of functions --------------------- ---------------------------------------------------------------------- All built-in primitives are Lisp objects of type Lisp_Subr. They point to a struct Lisp_Subr, which contains a pointer to the C function for the primitive, the minimum and maximum number of arguments, a string holding the name of the primitive, and a few other things. The corresponding C function is named by prepending an 'F' to the primitive's name, and the corresponding struct Lisp_Subr is named by prepending an 'S' to the primitive's name. The macro DEFUN is used to automate the C declarations of primitives. ---------------------------------------------------------------------- ------------------------------- obarray ------------------------------ ---------------------------------------------------------------------- An obarray is a hash table that indexes strings to their corresponding symbols. obarrays are Lisp vectors of symbols. Chaining is done through a special, normally inaccessible field of struct Lisp_Symbol. Emacs maintains a global obarray for all the interned strings. OBARRAY_SIZE (manifest constant) [lread.c] is the size of the global obarray, which is 509. Vobarray holds the global obarray. init_obarray() [lread.c] allocates space for the global obarray and initializes the obarray, which involves creating a few important symbols and putting NIL into the obarray. hash_string() [lread.c] hashes a string into an unsigned int. check_obarray() [lread.c] makes sure that an obarray passed as an argument to a Lisp function is the right type. oblookup() [lread.c] looks up a string in an obarray, returning the corresponding symbol if the string is found, or returning the hash value otherwise. map_obarray() [lread.c] applies a C function to every element in an obarray. Fmapatoms() [lread.c] is a Lisp primitive that does the same thing as map_obarray(). Adding to an obarray is performed within the Fintern() function. ---------------------------------------------------------------------- ---------------------------- point motion ---------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- ------------------------------ redisplay ----------------------------- ---------------------------------------------------------------------- 1. Important variables selected_screen The currently selected screen (struct screen *). selected_window The currently selected window on the currently selected screen (struct window *). (struct screen).garbaged True if the screen needs to be completely redisplayed. (struct screen).visible True if the screen is currently visible. Changed by make-screen-visible and make-screen-invisible. windows_or_buffers_changed Non-zero if any part of the display needs to change. noninteractive True if we are not in an interactive Emacs (if Emacs was invoked with the -batch option). In this case, nothing is displayed except for messages sent with message(), which are sent to stderr. in_display True if we are currently updating the display. Vscreen_list List of all the screens that currently exist. clip_changed ? redraw_mode_line Non-zero if the mode line for the current screen needs to be redrawn. ---------------------------------------------------------------------- ------------------------------- screens ------------------------------ ---------------------------------------------------------------------- [from screen.h] struct screen { int size; struct Lisp_Vector *next; /* glyphs as they appear on the screen */ struct screen_glyphs *current_glyphs; /* glyphs we'd like to appear on the screen */ struct screen_glyphs *desired_glyphs; /* Cost of inserting 1 line on this screen */ int *insert_line_cost; /* Cost of deleting 1 line on this screen */ int *delete_line_cost; /* Cost of inserting n lines on this screen */ int *insert_n_lines_cost; /* Cost of deleting n lines on this screen */ int *delete_n_lines_cost; /* glyphs for the mode line */ struct screen_glyphs *temp_glyphs; /* Intended cursor position of this screen. Measured in characters, counting from upper left corner within the screen. */ int cursor_x; int cursor_y; /* Is the cursor turned off? */ int cursor_erased; /* Actual cursor position of this screen. (Not used for terminal screens.) */ int phys_cursor_x; int phys_cursor_y; /* Size of this screen, in units of characters. */ int height; int width; /* New height and width for pending size change. 0 if no change pending. */ int new_height, new_width; /* Name of this screen: a Lisp string. */ Lisp_Object name; /* This screen's root window. Every screen has one. If the screen has only a minibuffer window, this is it. Otherwise, if the screen has a minibuffer window, this is its sibling. */ Lisp_Object root_window; /* This screen's selected window. Each screen has its own window hierarchy and one of the windows in it is selected within the screen. The selected window of the selected screen is Emacs's selected window. */ Lisp_Object selected_window; /* This screen's minibuffer window. Most screens have their own minibuffer windows, but only the selected screen's minibuffer window can actually appear to exist. */ Lisp_Object minibuffer_window; /* A copy of the global Vbuffer_list, to maintain a per-screen buffer ordering. The Vbuffer_list variable and the buffer_list slot of each screen contain exactly the same data, just in different orders. */ Lisp_Object buffer_alist; /* Parameter alist of this screen. These are the parameters specified when creating the screen or modified with modify-screen-parameters. */ Lisp_Object param_alist; /* Vector representing the menubar currently displayed. See menubar.c. */ Lisp_Object menubar_data; /* The output method says how the contents of this screen are displayed. It could be using termcap, or using an X window. */ enum output_method output_method; /* A structure of auxiliary data used for displaying the contents. struct x_display is used for X window screens; it is defined in xterm.h. */ union display { struct x_display *x; int nothing; } display; /* Nonzero if last attempt at redisplay on this screen was preempted. */ char display_preempted; /* Nonzero if screen is currently displayed. */ char visible; /* Nonzero if window is currently iconified. This and visible are mutually exclusive. */ char iconified; /* Nonzero if this screen should be redrawn. */ char garbaged; /* True if screen actually has a minibuffer window on it. 0 if using a minibuffer window that isn't on this screen. */ char has_minibuffer; /* 0 means, if this screen has just one window, show no modeline for that window. */ char wants_modeline; /* True if screen's root window can't be split. */ char no_split; /* Storage for messages to this screen. */ char *message_buf; /* list of faces */ struct face** faces; int n_faces; /* the lisp data (shadowing the C data) */ Lisp_Object face_alist; #ifdef ENERGIZE DisplayContext* display_context; #endif }; /* Each X screen object points to its own struct x_display object in the display.x field. The x_display structure contains all the information that is specific to X windows. */ struct x_display { /* Position of the X window (x and y offsets in root window). */ int left_pos; int top_pos; /* Size of the X window in pixels, including internal border. */ int pixel_height, pixel_width; #ifdef DEADX /* Here are the Graphics Contexts for the default font. */ GC normal_gc; /* Normal video */ GC reverse_gc; /* Reverse video */ GC cursor_gc; /* cursor drawing */ #ifdef LINE_INFO_COLUMN GC line_info_gc; /* lineinfo column */ #endif #endif /* Width of the internal border. This is a line of background color just inside the window's border. When the screen is selected, a highlighting is displayed inside the internal border. */ int internal_border_width; #ifdef LINE_INFO_COLUMN /* Width of the line info column. The line info column appears to the left of the left margin, inside the internal border. It is used to display glyphs related to each line. */ int line_info_column_width; int default_line_info_column_width; #ifdef DEADX PIX_TYPE line_info_background_pixel; #endif FONT_TYPE *font; #endif int text_height; /* Flag to set when the X window needs to be completely repainted. */ int needs_exposure; #ifdef DEADX /* The widget of this screen. This is the window of a "shell" widget. */ Widget widget; /* The XmPanedWindows... */ Widget column_widget; #ifdef LINE_INFO_WIDGET Widget row_widget; /* The widget of the line-info widget */ Widget lineinfo_widget; #endif /* The widget of the edit portion of this screen; the window in "window_desc" is inside of this. */ Widget edit_widget; Widget menubar_widget; #endif #ifdef ENERGIZE /* The Energize property-sheets. The current_ slots are the ones which are actually on the screen. The desired_ slots are the ones which should be there. Redisplay synchs these. */ int *current_psheets; int *desired_psheets; int current_psheet_count; int desired_psheet_count; Lisp_Object current_psheet_buffer; Lisp_Object desired_psheet_buffer; #endif /* This is true if we own the window, that is, it is not a window that was created by another process. If we don't own the window, we aren't allowed to destroy it. "The window" referred to is always window_desc; if USE_WIDGET is true, we always own the window inside of the edit_widget. */ char own_window; /* Whether this screen has the keyboard focus locked on it, whether the mouse is in this screen, and whether this is the screen currently receiving keyboard input. In point-to-type mode, focus_p will never be true, and mouse_p and input_p will be the same. In click-to-type mode, input_p will be the same as focus_p, and mouse_p will vary. Generally, input_p is the only interesting value, but the other two are necessary state to correctly interpret the interactions between FocusIn, FocusOut, EnterNotify, and LeaveNotify events. These must be per-screen properties instead of global variables, because screens are not necessarily on the same monitor, so more than one can have a mouse, and more than one can have keyboard focus. */ char focus_p; char mouse_p; char input_p; /* 1 if the screen is completely visible on the display, 0 otherwise. if 0 the screen may have been iconified or may be totally or parrtially hidden by another X window */ char totally_visible_p; }; [ "text_height" is (more or less) the maximum height of any character that might be displayed on the screens; specifically, it is the maximum, over all the fonts displayed on the screen, of the sum of the font's "ascent" and "descent" values. ] A "screen" corresponds to one window in the underlying windowing system. In a non-windowing environment, there is only one screen, corresponding to the entire screen. Each "screen" is divided up into non-overlapping "windows", which the windowing system knows nothing about. Screens are allocated like windows -- i.e. allocated as vectors of the proper size, and then the type of the Lisp_Object is set to Lisp_Screen. The screens structure contains screen-specific properties such as the screen's size, the cursor position, whether the cursor is displayed, the tree of windows that the screen consists of, what the menus look like, insertion/deletion costs, etc. The actual text on the screen is held in "current_glyphs", a pointer to a struct screen_glyphs (see "glyphs"). "desired_glyphs" points to another struct screen_glyphs, containing the text that the screen should next display. The window-system-specific information is held in "display" (and should be a void pointer). display.nothing is for accessing the value raw -- nothing == 0 means that the screen has been deleted (it will be garbage- collected along with the rest of the vectors); nothing == 1 means that this is a "terminal" screen (a screen corresponding to the entire physical screen, used in non-windowing systems). Window-system-specific stuff is done by calling x_* functions; these functions manipulate the display structure. 1. variables Vscreen_list points to a list of all the screens, chained through the "next" field. selected_screen is the screen currently selected. 2. creating a screen make_screen(), make_screen_without_minibuffer(), make_minibuffer_screen(), and make_terminal_screen() allocate and initialize a struct screen. A root window (and optionally a minibuffer window) is allocated. The glyph structures are not allocated. make_screen() actually does the work and takes a parameter indicating whether to create a minibuffer window. make_screen_without_minibuffer() uses make_screen() to create a screen without its own minibuffer and gives the screen either the specified minibuffer or the global minibuffer, taken from "global-minibuffer-screen" (see "minibuffers"). make_minibuffer_screen() makes a screen without a minibuffer and then converts the root window into a minibuffer. make_terminal_screen() creates a screen and sets some parameters to indicate that it's actually the screen corresponding to stdio. Only make_terminal_screen() changes Vscreen_list. delete-screen deletes a screen. This involves setting display.nothing to 0, removing the screen from Vscreen_list, and calling x_destroy_window() to do the physical work. Checks are performed to see if the currently selected screen is being deleted, the global minibuffer screen is being deleted, or the only screen is being deleted. 3. selecting a screen select-screen calls select_screen(), which sets selected_screen, optionally runs the old screen's deselect-screen hook and the new screen's select-screen hook, selects the screen's "selected_window", sets the minibuffer, and calls x_new_selected_screen() and x_focus_screen() to do the display work. 4. information about screens selected-screen, window-screen, screen-root-window, screenp, and screen-selected-window return properties of screens. 5. The screen list Vscreen_list is the list of all the screens. Elements are deleted from it using Fdelq() and are added manually to the front. screen-list, next-screen, next_screen(), and prev_screen() return information about the list of screens. 5. mouse position read_mouse_position(), read-mouse-position, set-mouse-position [need more about this] 6. screen visibility make-screen-visible, make-screen-invisible, iconify-screen, deiconify-screen, screen-visible-p, visible-screen-list [more about this], raise-screen, lower-screen, screen-totally-visible-p 7. screen properties screen-height, screen-width, screen-name, internal_set_screen_size(), set-screen-height, set-screen-width, set-screen-size, set-screen-position, 8. coordinates coordinates_in_window(), coordinates-in-window-p, window_from_coordinates(), locate-window-from-coordinates 9. misc choose_minibuf_screen(), syms_of_screen() 10. X functions and the screen.c functions that call them x_new_selected_screen(screen *s) called by: select_screen() x_focus_screen(screen *s) called by: select_screen() x_destroy_window(screen *s, union display displ) called by: delete-screen x_read_mouse_position(screen *s, int *x, int *y) called by: read_mouse_position() x_set_mouse_position(screen *s, int x, int y) called by: set-mouse-position x_make_screen_visible(screen *s) called by: make-screen-visible, deiconify-screen x_make_screen_invisible(screen *s) called by: make-screen-invisible x_iconify_screen(screen *s) called by: iconify-screen x_report_screen_params(screen *s, Lisp_Object *alist) called by: screen-parameters x_set_screen_values(screen *s, Lisp_Object alist) called by: modify-screen-parameters x_set_window_size(screen *s, int cols, int rows) called by: internal_set_screen_size() x_set_offset(screen *s, int x, int y) called by: set-screen-position x_raise_screen(screen *s, int called by: raise-screen x_lower_screen(screen *s) called by: lower-screen ---------------------------------------------------------------------- ------------------------------- symbols ------------------------------ ---------------------------------------------------------------------- struct Lisp_Symbol { struct Lisp_String *name; Lisp_Object value; Lisp_Object function; Lisp_Object plist; struct Lisp_Symbol *next; /* -> next symbol in this obarray bucket */ }; [intern??] ---------------------------------------------------------------------- -------------- symbol-values and buffer-local variables -------------- ---------------------------------------------------------------------- (code is contained in data.c) Normally the value field of a symbol contains a Lisp object that is the value of that symbol. In some cases, however (depending on the type of the object stored in the field), the value must be obtained by indirection. Here are the special types, and their descriptions in lisp.h: Lisp_Intfwd Forwarding pointer to an int variable. This is allowed only in the value cell of a symbol, and it means that the symbol's value really lives in the specified int variable. XINTPTR(obj) points to the int variable. Lisp_Boolfwd Boolean forwarding pointer to an int variable. This is like Lisp_Intfwd except that the ostensible "value" of the symbol is t if the int variable is nonzero, nil if it is zero. XINTPTR(obj) points to the int variable. Lisp_Objfwd Forwarding pointer to a Lisp_Object variable. This is allowed only in the value cell of a symbol, and it means that the symbol's value really lives in the specified variable. XOBJFWD(obj) points to the Lisp_Object variable. Lisp_Buffer_Local_Value Used in a symbol value cell when the symbol's value is per-buffer. The actual contents are a cons cell which starts a list like this: (REALVALUE BUFFER CURRENT-ALIST-ELEMENT . DEFAULT-VALUE)). BUFFER is the last buffer for which this symbol's value was made up to date. CURRENT-ALIST-ELEMENT is a pointer to an element of BUFFER's b_local_var_alist, that being the element whose car is this variable. Or it can be a pointer to the (CURRENT-ALIST-ELEMENT .DEFAULT-VALUE), if BUFFER does not have an element in its alist for this variable (that is, if BUFFER sees the default value of this variable). If we want to examine or set the value and BUFFER is current, we just examine or set REALVALUE. If BUFFER is not current, we store the current REALVALUE value into CURRENT-ALIST-ELEMENT, then find the appropriate alist element for the buffer now current and set up CURRENT-ALIST-ELEMENT. Then we set REALVALUE out of that element, and store into BUFFER. If we are setting the variable and the current buffer does not have an alist entry for this variable, an alist entry is created. Note that REALVALUE can be a forwarding pointer. Each time it is examined or set, forwarding must be done. Lisp_Some_Buffer_Local_Value Like Lisp_Buffer_Local_Value with one difference: merely setting the variable while some buffer is current does not cause that buffer to have its own local value of this variable. Only make-local-variable does that. Lisp_Buffer_Objfwd Like Lisp_Objfwd except that value lives in a slot in the current buffer. Value is byte index of slot within buffer Lisp_Void In symbol value cell, means var is unbound. In symbol function cell, means function name is undefined. (from data.c, section "symbol-values") C: do_symval_forwarding(), store_symval_forwarding(), swap_in_symval_forwarding(), default_value() Lisp: symbol-value, set, default-boundp, default-value, set-default, setq-default, make-variable-buffer-local, make-local-variable, kill-local-variable The forwarding types Lisp_Intfwd, Lisp_Boolfwd, and Lisp_Objfwd are used when a Lisp variable mirrors the value of some C variable in the code. [examples here] Such Lisp variables are defined with defvar_lisp(), defvar_lisp_nopro(), defvar_bool(), and defvar_int() [lread.c]. Often, the equivalent macros DEFVARLISP(), DEFVARBOOL(), DEFVARINT(), DEFVAR_LISP(), DEFVAR_LISP_NOPRO(), DEFVAR_BOOL(), and DEFVAR_INT() are used instead. All of these functions simply intern the specified variable and set the symbol's value field to the proper type and pointer. defvar_lisp() calls staticpro() on the Lisp variable pointed to, while defvar_lisp_nopro() does not (see "allocation"). The type Lisp_Buffer_Objfwd refers to Lisp variables whose values mirror per-buffer C variables held in fields ("slots") in struct buffer (each such slot contains a Lisp object, and the slots are defined in bufslots.h; see "buffers" for more information). The value stored in the symbol's value field is a byte offset into a struct buffer. defvar_per_buffer() or the equivalent macros DEFVARPERBUFFER() or DEFVAR_PER_BUFFER() define Lisp variables of this type. Some such variables have separate values for every buffer; others have default values, just like for normal buffer-local variables. The special struct buffer "buffer_local_symbols" contains, in each slot for which a shadowing Lisp variable has been defined, a pointer to that variable's symbol. defvar_per_buffer() sets this. struct buffer "buffer_local_flags" indicates, for each slot, what the status of the corresponding variable is: 0 in the slot means no variable exists; -1 means the variable is always local to each buffer; otherwise the slot contains a mask value. This mask value references a bit in the struct buffer field "local_var_flags" indicating whether the corresponding variable has its own value in this buffer. Note that even when a buffer does not have a local value for a particular slot variable, the slot in that buffer will always contain the correct (i.e. default) value. Setting a default value sets the slots of all buffers that do not have a local value. struct buffer "buffer_defaults" contains these default values, for each slot that has one. init_buffer_once() initializes these special structs, and syms_of_buffer() defines most of the Lisp variables that shadow slots. do_symval_forwarding() accesses the value of a symbol, correctly dealing with the four types of forwarding (it does not deal with normal buffer-local variables, though -- see below). Similarly, store_symval_forwarding() stores a value in a symbol and deals with forwarding types (it, too, does not deal with normal buffer-local variables, nor does it change the flag in local_var_flags if a slot variable formerly had no local value). Note that symbol-value does not actually call do_symval_forwarding(), but does exactly the equivalent thing when dealing with forwarding pointers. Normal buffer-local variables are tricky. For each buffer that has its own local value of a variable, there is an entry in the field "local_var_alist" (an assoc-list associating symbols with values) in the corresponding struct buffer. In the value field of each buffer-local variable's symbol is a list, as follows: (REALVALUE BUFFER CURRENT-ALIST-ELEMENT . DEFAULT-VALUE) BUFFER is the last buffer in which this variable was accessed or changed; REALVALUE is the current value of this variable in that buffer; and CURRENT-ALIST-ELEMENT points to the entry for this variable in that buffer's local_var_alist, or points to the cons (CURRENT-ALIST-ELEMENT . DEFAULT-VALUE) if no local value exists. Note that the assoc-list entry pointed to by CURRENT-ALIST-ELEMENT may not contain the most recent value of the variable, but REALVALUE always will. swap_in_symval_forwarding() returns the value of a buffer-local variable in the current buffer, and, if necessary, updates the list above for the current buffer. There's some more tricky complexity here depending on whether the buffer-local variable is of type Lisp_Buffer_Local_Variable (if the variable doesn't have a local value and you set it, a local value is created) or Lisp_Some_Buffer_Local_Variable (local values are only created by calling make-local-variable) and depending on whether the default value for the variable (i.e. that value the variable had when make-local-variable or make-variable-buffer-local) was a forwarding pointer. Look in set, symbol-value, default-value, default_value(), default-boundp, set-default, setq-default, make-local-variable, make-variable-buffer-local, kill-local-variable, kill-all-local-variables [buffer.c]. It's truly ugly. ---------------------------------------------------------------------- ------------------------------ windows ------------------------------- ---------------------------------------------------------------------- [from window.h] /* Windows are allocated as if they were vectors, but then the Lisp data type is changed to Lisp_Window. They are garbage collected along with the vectors. All windows in use are arranged into a tree, with pointers up and down. Windows that are leaves of the tree are actually displayed and show the contents of buffers. Windows that are not leaves are used for representing the way groups of leaf windows are arranged on the screen. Leaf windows never become non-leaves. They are deleted only by calling delete-window on them (but this can be done implicitly). Combination windows can be created and deleted at any time. A leaf window has a non-nil buffer field, and also has markers in its start and pointm fields. Non-leaf windows have nil in these fields. Non-leaf windows are either vertical or horizontal combinations. A vertical combination window has children that are arranged on the screen one above the next. Its vchild field points to the uppermost child. The parent field of each of the children points to the vertical combination window. The next field of each child points to the child below it, or is nil for the lowest child. The prev field of each child points to the child above it, or is nil for the highest child. A horizontal combination window has children that are side by side. Its hchild field points to the leftmost child. In each child the next field points to the child to the right and the prev field points to the child to the left. The children of a vertical combination window may be leaf windows or horizontal combination windows. The children of a horizontal combination window may be leaf windows or vertical combination windows. At the top of the tree are two windows which have nil as parent. The second of these is minibuf_window. The first one manages all the screen area that is not minibuffer, and is called the root window. Different windows can be the root at different times; initially the root window is a leaf window, but if more windows are created then that leaf window ceases to be root and a newly made combination window becomes root instead. In any case, prev of the minibuf window is the root window and next of the root window is the minibuf window. To find the root window at any time, do XWINDOW (minibuf_window)->prev. */ struct window { /* The first two fields are really the header of a vector */ /* The window code does not refer to them. */ int size; struct Lisp_Vector *vec_next; /* The screen this window is on. */ Lisp_Object screen; /* t if this window is a minibuffer window. */ Lisp_Object mini_p; /* Following child (to right or down) at same level of tree */ Lisp_Object next; /* Preceding child (to left or up) at same level of tree */ Lisp_Object prev; /* First child of this window. */ /* vchild is used if this is a vertical combination, hchild if this is a horizontal combination. */ Lisp_Object hchild, vchild; /* The window this one is a child of. */ Lisp_Object parent; /* The upper left corner coordinates of this window, as integers relative to upper left corner of screen = 0, 0 */ Lisp_Object left; Lisp_Object top; /* The size of the window */ Lisp_Object height; Lisp_Object width; /* The buffer displayed in this window */ /* Of the fields vchild, hchild and buffer, only one is non-nil. */ Lisp_Object buffer; /* A marker pointing to where in the text to start displaying */ Lisp_Object start; /* A marker pointing to where in the text point is in this window, used only when the window is not selected. This exists so that when multiple windows show one buffer each one can have its own value of point. */ Lisp_Object pointm; /* Non-nil means next redisplay must use the value of start set up for it in advance. Set by scrolling commands. */ Lisp_Object force_start; /* Number of columns display within the window is scrolled to the left. */ Lisp_Object hscroll; /* Number saying how recently window was selected */ Lisp_Object use_time; /* Unique number of window assigned when it was created */ Lisp_Object sequence_number; /* No permanent meaning; used by save-window-excursion's bookkeeping */ Lisp_Object temslot; /* text.modified of displayed buffer as of last time display completed */ Lisp_Object last_modified; /* Value of point at that time */ Lisp_Object last_point; /* buf.face_change as of last time display completed */ Lisp_Object last_facechange; /* The rest are currently not used or only half used */ /* Screen coords of point at that time */ Lisp_Object last_point_x; Lisp_Object last_point_y; /* Screen coords of mark as of last time display completed */ /* May be nil if mark does not exist or was not on screen */ Lisp_Object last_mark_x; Lisp_Object last_mark_y; /* Number of characters in buffer past bottom of window, as of last redisplay that finished. */ Lisp_Object window_end_pos; /* t if window_end_pos is truly valid. This is nil if nontrivial redisplay is preempted since in that case the screen image that window_end_pos did not get onto the screen. */ Lisp_Object window_end_valid; /* Vertical position (relative to window top) of that buffer position of the first of those characters */ Lisp_Object window_end_vpos; /* Non-nil means must regenerate mode line of this window */ Lisp_Object redo_mode_line; /* Non-nil means current value of `start' was the beginning of a line when it was chosen. */ Lisp_Object start_at_line_beg; /* Display-table to use for displaying chars in this window. Nil means use the buffer's own display-table. */ Lisp_Object display_table; /* Non-nil means window is marked as dedicated. */ Lisp_Object dedicated; }; 1. general-purpose make_window() creates and initializes a new window. As described above, a struct window is allocated and garbage-collected as a vector. This works because struct window and struct Lisp_Vector share their first few fields; the remaining fields of struct window are all Lisp_Object's, and these fields appear simply as elements of the vector. "sequence_number" is used to assign a sequence number to a window; this variable is incremented each time a window is created. windowp asks whether a particular object is a Lisp_Window. selected-window returns the window that the cursor appears in; this is held in "selected_window". ---------------------------------------------------------------------- ----------------------------- X interface ---------------------------- ---------------------------------------------------------------------- x_write_glyphs() ---------------------------------------------------------------------- -------------------------------- files ------------------------------- ---------------------------------------------------------------------- ---------------------------------------------------------------------- ColumnWidget.c ---------------------------------------------------------------------- some X stuff --? ---------------------------------------------------------------------- EmacsShell.c ---------------------------------------------------------------------- more X stuff --? ---------------------------------------------------------------------- ScreenWidget.c ---------------------------------------------------------------------- more X stuff --? ---------------------------------------------------------------------- abbrev.c ---------------------------------------------------------------------- Implements minor-mode "Abbrev". [section ??] [more detail here] Lisp functions: make-abbrev-table, clear-abbrev-table, define-abbrev, define-global-abbrev, define-mode-abbrev, abbrev-symbol, abbrev-expansion, expand-abbrev, unexpand-abbrev, insert-abbrev-table-description, define-abbrev-table Lisp variables: abbrev-table-name-list, global-abbrev-table, fundamental-mode-abbrev-table, last-abbrev, last-abbrev-text, last-abbrev-location, abbrev-start-location, abbrev-start-location-buffer, local-abbrev-table, abbrevs-changed, abbrev-all-caps, pre-abbrev-expand-hook C functions: write_abbrev(), describe_abbrev(), syms_of_abbrev() C variables: ---------------------------------------------------------------------- alloc.c (** system-dependent **) ---------------------------------------------------------------------- A. low-level allocation C functions: malloc_warning_1(), malloc_warning(), memory_full(), xmalloc(), xrealloc() B. allocation of particular types 1. extents: EXTENT_BLOCK_SIZE, DUP_BLOCK_SIZE, struct extent_block, struct dup_block, extent_block, extent_block_index, extent_free_list, dup_block, dup_block_index, dup_free_list, init_extents(), make_extent(), make_extent_replica() 2. floats: FLOAT_BLOCK_SIZE, struct float_block, float_block, float_block_index, float_free_list, init_float(), free_float(), make_float() 3. conses: CONS_BLOCK_SIZE, struct cons_block, cons_block, cons_block_index, cons_free_list, init_cons(), free_cons() Lisp: cons, list, make-list 4. vectors: all_vectors Lisp: make-vector, vector, make-byte-code 5. symbols: SYMBOL_BLOCK_SIZE, struct symbol_block, symbol_block, symbol_block_index, symbol_free_list, init_symbol() Lisp: make-symbol 6. markers: MARKER_BLOCK_SIZE, struct marker_block, marker_block, marker_block_index, marker_free_list, init_marker() Lisp: make-marker 7. strings: PAD, ROUND_UP_STRING_SIZE(), STRING_FULL_SIZE(), STRING_BLOCK_SIZE, STRING_CHARS_BLOCK_SIZE, struct string_chars, SLOT_OFFSET(), CHARS_TO_STRING_CHAR(), struct string_chars_block, struct string_block, string_block, string_block_index, string_free_list, current_string_chars_block, first_string_chars_block, NONRELOCATING_STRING_SIZE(), BIG_STRING_SIZE(), init_strings(), make_string_internal(), allocate_string_chars(), make_uninit_string(), make_string_from_buffer, make_string(), build_string() Lisp: make-string C. pure storage C: tl, tf, ts, make_pure_string(), pure_cons(), make_pure_float(), make_pure_vector() Lisp: purecopy D. garbage collection C: gcprolist, NSTATICS, staticvec[], staticidx, staticpro(), ARRAY_MARK_FLAG, BTL_before_Fgarbage_collect_stub(), total_conses, total_markers, total_symbols, total_vector_size, total_string_size, total_strings, total_short_strings, total_free_strings, total_free_conses, total_free_markers, total_free_symbols, total_free_flota, total_floats, total_free_events, total_events, mark_one_extent(), mark_extents(), total_free_extents, total_extents, total_free_dups, total_dups, current_pointer_shape, mark_object(), mark_buffer(), mark_event(), mark_command_event_queue(), gc_sweep(), compact_string_chars(), init_alloc_once(), init_alloc(), syms_of_alloc() Lisp: garbage-collect alloca.c (** system-dependent **) Implementation of alloca(), which allocates memory space (originally off the stack) that is automatically freed upon exit of the function. This version actually uses malloc(), and deallocates the space at some point after the calling function has exited (upon each call to alloca() it checks for stuff allocated in a lower stack frame) ---------------------------------------------------------------------- buffer.c ---------------------------------------------------------------------- Lots of stuff relating to buffers. Code to create, destroy, select and deselect buffers, return or change properties of a buffer, and do other things that apply to a buffer as a whole. No code to change the text in a buffer or do low-level buffer-local-variable stuff. current_buffer, all_buffers, buffer_defaults, buffer_local_flags, buffer_local_symbols, check_protected_fields, nsberror(), find_file_compare_truenames, file_file_use_truenames, push_buffer_alist(), delete_from_buffer_alist(), buffer_count, reset_buffer(), reset_buffer_local_variables(), count_modified_buffers(), record_buffer(), internal_set_buffer(), validate_region(), init_buffer_once(), init_buffer(), syms_of_buffer(), keys_of_buffer() Lisp: [V]buffer-defaults, [V]buffer-local-symbols, [V]buffer-alist, [V]before-change-function, [V]after-change-function, [V]first-change-function, [Q]fundamental-mode, [Q]mode-class, [Q]permanent-local, [Q]protected_field, [QS]Fundamental, buffer-list, get-buffer, get-file-buffer, get-buffer-create, generate-new-buffer, buffer-name, buffer-file-name, buffer-local-variables, buffer-dedicated-screen, set-buffer-dedicated-screen, buffer-modified-p, set-buffer-modified-p, rename-buffer, other-buffer, buffer-disable-undo, buffer-enable-undo, switch-to-buffer, pop-to-buffer, current-buffer, set-buffer, barf-if-buffer-read-only, bury-buffer, erase-buffer, kill-all-local-variables, region-fields, kill-buffer, buffer-modified-tick ---------------------------------------------------------------------- bytecode.c ---------------------------------------------------------------------- Contains the function "byte-code", which is the byte-code interpreter. It simulates a simple stack-based machine. ---------------------------------------------------------------------- callint.c ---------------------------------------------------------------------- Implements the functions call-interactively and prefix-numeric-value. call-interactively scans through the function looking for an interactive specification, and requests arguments for the user according to this specification. These arguments are then passed to the function. C: num_input_chars, quotify_args(), callint_argfuns[], check_mark(), syms_of_callint() Lisp: [V]prefix-arg, [V]current-prefix-arg, [Q]minus, [Q]call-interactively, [V]command-history, [V]command-debug-status, [Q]command-debug-status, interactive, [V]current-mouse-event, call-interactively, prefix-numeric-value ---------------------------------------------------------------------- callproc.c (** system-dependent **) ---------------------------------------------------------------------- Implements call-process and call-process-region, which synchronously spawn a subprocess and place the output in a specified buffer. C: synch_process_alive, synch_process_death, synch_process_retcode, call_process_cleanup(), fork_error, report_fork_error(), child_setup(), init_callproc(), syms_of_callproc() Lisp: [V]exec-path, [V]exec-directory, [V]shell-file-name, [V]process-environment, call-process, call-process-region, ---------------------------------------------------------------------- casefiddle.c ---------------------------------------------------------------------- Implements Lisp functions that change the case of text. Actual work is done by casify_object() and casify_region(). They call macros UPCASE(), DOWNCASE(), etc. defined in lisp.h. These macros work by looking at the case table for the buffer. See also casetab.c. C: enum case_action, casify_object(), casify_region(), upcase_initials_region(), operate_on_word(), syms_of_casefiddle(), keys_of_casefiddle() Lisp: upcase, downcase, capitalize, upcase-region, downcase-region, capitalize-region, upcase-word, downcase-word, capitalize-word ---------------------------------------------------------------------- casetab.c ---------------------------------------------------------------------- Implements functions that operate on case tables. Case tables are built-in buffer properties, stored in a struct buffer. The case-changing functions in casefiddle.c look at the case tables. C: check_case_table(), set_case_table(), compute_trt_inverse(), init_casetab_once(), syms_of_casetab() Lisp: [Q]case-table-p, [V]ascii-downcase-table, [V]ascii-upcase-table, [V]ascii-canon-table, [V]ascii-eqv-table, case-table-p, current-case-table, standard-case-table, set-case-table, set-standard-case-table ---------------------------------------------------------------------- cm.c (** system-dependent **) ---------------------------------------------------------------------- Provides an optimized, terminal-independent method for moving the cursor to a specified location. cmgoto() is the function that does this. C: cost, evalcost(), cmputc(), addcol(), cmcostinit(), COST(), CMCOST(), calccost(), cmgoto(), Wcm_clear(), Wcm_init() ---------------------------------------------------------------------- cmds.c ---------------------------------------------------------------------- Implements basic cursor motion and editing commands. internal_self_insert() does the work of inserting a character, and has special checks for overwrite mode, abbrevs (calls Fexpand_abbrev()), auto-fill-mode (calls the current buffer's auto-fill function), and paren-blinking (calls Vblink_paren_function). Not pretty. [what about zmacs_region_stays?] C: zmacs_region_stays, internal_self_insert(), syms_of_cmds(), keys_of_cmds() Lisp: [Q]kill-forward-chars, [Q]kill-backward-chars, [V]blink-paren-function, forward-char, backward-char, forward-line, beginning-of-line, end-of-line, delete-char, delete-backward-char, self-insert-command, newline ---------------------------------------------------------------------- crt0.c (** system-dependent **) ---------------------------------------------------------------------- This is a replacement for the standard system-dependent start-up routine _start(). This replacement is necessary for VAX 4.2 but not for most other machines. ---------------------------------------------------------------------- data.c ---------------------------------------------------------------------- Implements basic data manipulation routines for the Lisp interpreter and some error-handling functions. Includes code to handle buffer-local variables. 1. errors C: wrong_type_argument(), pure_write_error(), args_out_of_range(), args_out_of_range_3(), arith_error() 2. integers C: make_number(), sign_extend_temp, sign_extend_lisp_int() 3. data type predicates Lisp: eq, null, consp, atom, listp, nlistp, symbolp, vectorp, stringp, arrayp, sequencep, bufferp, markerp, integer-or-marker-p, subrp, compiled-function-p, char-or-string-p, integerp, natnump, floatp, numberp, number-or-marker-p, extentp 4. list manipulation Lisp: car, car-safe, cdr, cdr-safe, setcar, setcdr 5. symbol manipulation Lisp: boundp, fboundp, makunbound, fmakunbound, symbol-function, symbol-plist, symbol-name, fset, setplist 6. symbol values C: do_symval_forwarding(), store_symval_forwarding(), swap_in_symval_forwarding(), default_value() Lisp: symbol-value, set, default-boundp, default-value, set-default, setq-default, make-variable-buffer-local, make-local-variable, kill-local-variable 8. vector manipulation C: Farray_length() Lisp: aref, aset 9. arithmetic C: enum comparison, arithcompare(); enum arithop, arith_driver(), float_arith_driver() Lisp: =, <, >, <=, >=, /=, zerop; int-to-string, string-to-int; +, -, *, /, %, max, min, logand, logior, logxor, ash, lsh, 1+, 1-, lognot 10. misc: syms_of_data(), init_data() ---------------------------------------------------------------------- dired.c (** system-dependent **) ---------------------------------------------------------------------- Includes routines to obtain file and directory information. Lisp: [V]completion-ignored-extensions, [Q]completion-ignore-case, directory-files, file-name-completion, file-attributes C: file_name_completion(), file_name_completion_stat(), make_time(), syms_of_dired() ---------------------------------------------------------------------- dispnew.c (** system-dependent **) ---------------------------------------------------------------------- 1. general variables C: screen_garbaged, display_completed, visible_bell, inverse_video, baud_rate, cursor_in_echo_area, selected_screen, ophys_lines, ophys_lines_length, termscript, Wcm, ospeed, in_display, delayed_size_change, delayed_screen_height, delayed_screen_width Lisp: [V]window-system, [V]window-system-version, [V]glyph-table, [V]standard-display-table, [Q]cursor-in-echo-area 2. C: make_screen_glyphs(), free_screen_glyphs(), remake_screen_glyphs(), line_hash_code(), line_draw_cost(), cancel_line(), clear_screen_records(), get_display_line(), safe_bcopy(), rotate_vector(), scroll_screen_lines(), preserve_other_columns(), cancel_my_columns(), direct_output_for_insert(), direct_output_forward_char(), count_blanks(), count_match(), update_line(), x_update_line(), update_screen(), scrolling(), pixel_to_glyph_translation(), window_change_signal(), change_screen_size(), bitch_at_user() Lisp: open-termscript, send-string-to-terminal, ding 3. initialization C: terminal_type, init_display(), syms_of_display() Lisp: initialize-first-screen ---------------------------------------------------------------------- doc.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- doprnt.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- editfns.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- editorside.c (** system-dependent **) ---------------------------------------------------------------------- ---------------------------------------------------------------------- elhash.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- emacs.c: ---------------------------------------------------------------------- This contains main(). main() is straightforward -- first it handles some of the low-level options and traps some signals, then it proceeds to initialization: 1) initialize the various data structures 2) intern the built-in symbols 3) set the default key bindings 4) miscellaneous (e.g. get the complete pathname of Emacs) 5) enter the editing loop (Frecursive_edit) ---------------------------------------------------------------------- environ.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- eval.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- event-Xt.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- event-alloc.c ---------------------------------------------------------------------- This module contains routines that manage "struct Lisp_Event", which holds the information for a single event. These routines allocate, de-allocate, and assist in garbage-collecting the structures. C: event_free_list, struct event_block, event_blocks, event_block_index, deinitialize_event(), get_more_events(), free_unmarked_events(), prepare_to_gc_events(), syms_of_event_alloc() Lisp: allocate-event, deallocate-event, copy-event Not terribly interesting. Events are managed just like cons cells. ---------------------------------------------------------------------- event-stream.c ---------------------------------------------------------------------- Lisp: [Q]undefined, [V]mouse-motion-handler, input-pending-p, next-event, next-command-event, read-char, discard-input, accept-process-output, dispatch-event, read-key-sequence C: event_stream, struct command_builder, command_event_queue, keystrokes, maybe_kbd_translate(), maybe_do_auto_save(), print_help(), execute_help_form(), detect_input_pending(), enqueue_command_event(), num_input_chars, next_event_internal(), deactivate_netconn(), dispatch_event_internal(), syms_of_event_stream() 2. timeout Lisp: sleep-for, sit-for, sleep-for-millisecs, add-timeout, disable-timeout C: lisp_number_to_milliseconds(), wait_delaying_user_input() 3. echo C: echo_char_event(), echo_prompt(), echo_keystrokes, maybe_echo_keys(), cancel_echoing() ---------------------------------------------------------------------- events.c ---------------------------------------------------------------------- 4. commands Lisp: [V]this-command-keys C: command_builder_find_leaf(), find_leaf_unwind(), recent_keys_ring, recent_keys_ring_index, this_command_keys_count, reset_this_command_keys, reset_this_command_keys_fn(), push_command_keys_vector(), push_recent_keys_vector(), store_recent_key(), command_builder_push(), command_builder_push_meta_hack(), self_insert_countdown, compose_command(), dispatch_command_event_internal(), dispatch_menu_event() ---------------------------------------------------------------------- extents.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- faces.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- fileio.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- filelock.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- filemode.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- floatfns.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- fns.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- free-hook.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- gmalloc.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- hash.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- indent.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- insdel.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- keyboard.c ---------------------------------------------------------------------- Lisp: [Q]disabled, [V]disabled-command-hook, [V]help-form, [V]global-function-map, [V]last-command-event, [V]last-command-char, [V]last-input-event, [V]last-input-char, [V]unread-command-event, [V]last-command, [V]this-command, [V]last-input-time, [V]mouse-left-hook, [V]mouse-enter-hook, [V]map-screen-hook, [V]unmap-screen-hook, [V]mouse-motion-handler, [Q]self-insert-command, [Q]forward-char, [Q]backward-char, [V]top-level, [V]keyboard-translate-table, command-execute, execute-extended-command, recent-keys, this-command-keys, recursion-depth, open-dribble-file, suspend-emacs, set-input-mode C: waiting_for_input, immediate_quit, help_char, interrupt_char, current_global_map, minibuf_level, echo_area_glyphs, command_loop_level, num_input_keys, dribble, meta_key, input_available_clear_word, interrupt_input, interrupts_deferred, flow_control, keyboard_init_hook, polling_period, polling_for_input, poll_suppress_count, input_poll_signal(), start_polling(), stop_polling(), input_available_signal(), map_prompt(), stuff_buffered_input(), set_waiting_for_input(), clear_waiting_for_input(), interrupt_signal(), init_keyboard(), syms_of_keyboard(), keys_of_keyboard() recursive-edit (main loop) C: recursive_edit_1(), recursive_edit_unwind(), cmd_error(), command_loop(), command_loop_2(), top_level_2(), top_level_1(), command_loop_1() Lisp: recursive-edit, top-level, exit-recursive-edit, abort-recursive-edit ---------------------------------------------------------------------- keymap.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- lastfile.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- libsst.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- lread.c: ---------------------------------------------------------------------- 1. Lisp I/O and parsing Lisp: [Q]read-char, [Q]get-file-char, [Q]standard-input, [Q]variable-documentation, [V]values, [V]standard-input, [V]after-load-alist, [V]load-path, get-file-char, load, locate-file, eval-buffer, eval-region, read, read-from-string, C: load_in_progress, instream, read_pure, read_from_string_index, read_from_string_limit, READCHAR, UNREAD(), readchar(), unreadchar(), load_unwind(), comlete_filename_p(), locate_file(), unreadpure(), readevalloop(), read0(), read_buffer_size, read_buffer, read_escape(), read1(), isfloat_string(), read_vector(), read_list(), init_read(), syms_of_read() 2. obarray Lisp: [V]obarray, intern, intern-soft, mapatoms C: initial_obarray, check_obarray(), intern(), oblookup(), hash_string(), map_obarray(), mapatoms_1(), OBARRAY_SIZE, init_obarray() 3. defining Lisp symbols C: defsubr(), defalias(), defvar_int(), defvar_bool(), defvar_lisp(), defvar_lisp_nopro(), defvar_per_buffer() ---------------------------------------------------------------------- macros.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- malloc.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- marker.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- menubar.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- menuitems.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- minibuf.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- mocklisp.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- play.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- pre-crt0.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- print.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- process.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- ralloc.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- realpath.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- regex.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- screen.c ---------------------------------------------------------------------- Routines dealing with "struct screen". This structure contains information about an Emacs "screen", which corresponds to a window in the windowing system. Each "screen" is divided up into Emacs's own non-overlapping "windows", which the windowing system knows nothing about. Many of these routines call routines in xterm.c to actually change the physical display. ---------------------------------------------------------------------- scroll.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- search.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- sunOS-fix.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- sunfns.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- syntax.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- sysdep.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- term.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- termcap.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- terminfo.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- tparam.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- undo.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- unexconvex.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- unexec.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- unexelf.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- unexencap.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- unexenix.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- unexhp9k800.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- unexmips.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- unexsunos4.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- vm-limit.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- vms-pp.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- vmsfns.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- vmsmap.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- vmsproc.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- window.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- xdisp.c (** system-dependent **) ---------------------------------------------------------------------- 1. variables C: noninteractive_need_newline, this_line_bufpos, this_line_endpos, this_line_vpos, this_line_start_hpos, this_line_buffer, previous_echo_glyphs, last_arrow_position, last_arrow_string, overlay_arrow_seen, scroll_step, blank_end_of_window, buffer_shared, cursor_vpos, cursor_hpos, debug_end_pos, mode_line_inverse_video, minibuf_prompt, minibuf_prompt_width, minibuf_prompt_pix_width, echo_area_buffer, echo_area_glyphs, redraw_mode_line, beg_unchanged, end_unchanged, unchanged_modified, clip_changed, windows_or_buffers_changed Lisp: [V]global-mode-string, [V]overlay-arrow-position, [V]overlay-arrow-string, [V]minibuffer-list 2. C: redraw_screen(), echo_area_display(), message_buf, message(), redisplay(), redisplay_preserving_echo_area(), mark_window_display_accurate(), redisplay_windows(), redisplay_window(), initialize_first_screen(), try_window(), try_window_id(), copy_rope() Lisp: redraw-display 3. C: char_glyphs(), measure_glyphs, GLYPH_SET_VALUE(), glyphs_from_char(), last_buffer, last_screen, last_buffer_modiff, last_buffer_facechange, last_buffer_extfrag, last_extfrag_from_pos, last_extfrag_to_pos, last_extfrag_face, displayed_glyphs, update_cache(), glyphs_from_bufpos(), new_run(), glyph_pixel_width(), stuff_glyph(), install_first_runs(), append_run(), append_glyph(), [it goes on] ---------------------------------------------------------------------- xfns.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- xselect.c ---------------------------------------------------------------------- ---------------------------------------------------------------------- xterm.c [2729 lines] [** system-dependent **] ---------------------------------------------------------------------- This module contains functions that interface between Emacs and the X display routines. ---------------------------------------------------------------------- xutils.c [158 lines] ---------------------------------------------------------------------- #fff# config.h free-hook.c ndir.h terminfo.c COPYING config.h-dist getpagesize.h param.h termopts.h ColumnWidget.c connmemory.h glyfs.h paths.h tparam.c ColumnWidget.h crt0.c gmalloc.c paths.h-dist uaf.h ColumnWidgetP.h data.c gnu.h play.c undo.c EmacsShell.c dir.h hash.c pre-crt0.c unexconvex.c EmacsShell.h dired.c hash.h print.c unexec.c EmacsShellP.h dispextern.h indent.c process.c unexelf.c FILES dispnew.c indent.h process.h unexencap.c Makefile disptab.h insdel.c puresize.h unexenix.c README doc.c ioctl.h pwd.h unexhp9k800.c ScreenWidget.c doprnt.c keyboard.c ralloc.c unexmips.c ScreenWidget.h editfns.c keymap.c realpath.c unexsunos4.c ScreenWidgetP.h editorside.c keymap.h regex.c vlimit.h abbrev.c editorside.h lastfile.c regex.h vm-limit.c acldef.h elhash.c lemacs* s/ vms-pp.c alloc.c emacs.c libsst.c screen.c vmsfns.c alloca.c environ.c libsst.h screen.h vmsmap.c backtrace.h eval.c line.h scroll.c vmspaths.h bitmaps.h event-Xt.c lisp.h search.c vmsproc.c blockio.h event-alloc.c lread.c sink.h vmsproc.h buffer.c event-stream.c lwlib/ sink11.h window.c buffer.h events.c m/ sink11mask.h window.h bufslots.h events.h m-delta.h sinkmask.h x11term.h bytecode.c extents-data.h macros.c sunOS-fix.c xdisp.c callint.c extents.c macros.h sunfns.c xfns.c callproc.c extents.h malloc.c syntax.c xselect.c casefiddle.c faces.c marker.c syntax.h xterm.c casetab.c faces.h mem_limits.h sysdep.c xterm.h chpdef.h fileio.c menubar.c tags xutils.c cm.c filelock.c menuitems.c term.c ymakefile cm.h filemode.c menuitems.h termcap.c cmds.c floatfns.c minibuf.c termchar.h commands.h fns.c mocklisp.c termhooks.h 323 1106 9924 ColumnWidget.c 497 1507 14727 EmacsShell.c 603 1850 18835 ScreenWidget.c 559 2134 17245 abbrev.c 2173 6770 55031 alloc.c 191 813 5217 alloca.c 1749 7269 57759 buffer.c 1160 3129 22649 bytecode.c 591 2436 17504 callint.c 581 2069 15289 callproc.c 268 1029 7432 casefiddle.c 251 952 7406 casetab.c 414 1651 10042 cm.c 373 1351 10019 cmds.c 534 2006 13346 crt0.c 1976 6797 53950 data.c 502 1936 14357 dired.c 2388 8358 67503 dispnew.c 465 1864 13021 doc.c 137 558 3635 doprnt.c 1363 5380 38484 editfns.c 4143 11784 114483 editorside.c 441 1244 11139 elhash.c 1126 3733 27718 emacs.c 316 1133 7780 environ.c 2340 8342 62039 eval.c 1607 5986 51340 event-Xt.c 266 1094 8091 event-alloc.c 1790 6902 55205 event-stream.c 748 2997 24085 events.c 2926 10080 85426 extents.c 974 3196 25777 faces.c 3117 12253 84469 fileio.c 401 1400 10011 filelock.c 199 747 4685 filemode.c 551 1801 12180 floatfns.c 1854 6656 46069 fns.c 606 1743 13957 free-hook.c 1154 4849 34011 gmalloc.c 438 1295 10260 hash.c 898 3406 25386 indent.c 642 2208 15464 insdel.c 1271 4773 35191 keyboard.c 2828 11260 87787 keymap.c 38 255 1464 lastfile.c 489 1810 10622 libsst.c 1578 5464 39596 lread.c 343 1177 9735 macros.c 895 4257 25043 malloc.c 312 1084 7945 marker.c 941 3576 28123 menubar.c 92 310 2368 menuitems.c 1391 5090 42280 minibuf.c 243 850 6078 mocklisp.c 241 745 5162 play.c 9 70 398 pre-crt0.c 1157 3873 31600 print.c 2439 8866 65634 process.c 419 1359 9626 ralloc.c 150 596 4512 realpath.c 1715 6664 44455 regex.c 1185 3743 30745 screen.c 618 2681 19707 scroll.c 1321 5852 38557 search.c 20 97 569 sunOS-fix.c 501 1770 13955 sunfns.c 1255 4553 33716 syntax.c 3742 12786 86731 sysdep.c 1476 4931 39070 term.c 672 2365 14167 termcap.c 50 274 1717 terminfo.c 275 1133 6768 tparam.c 301 1142 8200 undo.c 809 3347 21994 unexconvex.c 855 3498 23421 unexec.c 625 2733 22706 unexelf.c 116 375 3198 unexencap.c 262 1086 7723 unexenix.c 293 1215 9003 unexhp9k800.c 290 1065 8585 unexmips.c 294 1263 7858 unexsunos4.c 126 439 3000 vm-limit.c 242 1014 7117 vms-pp.c 960 3610 26453 vmsfns.c 224 893 6013 vmsmap.c 786 2399 17633 vmsproc.c 2734 9684 78257 window.c 3860 13490 111868 xdisp.c 2228 7365 63070 xfns.c 1849 7090 57502 xselect.c 2729 7694 73831 xterm.c 158 548 4387 xutils.c 91042 326028 2508090 total